diff --git a/.ci/Jenkinsfile b/.ci/Jenkinsfile index 530349ced..94070569e 100644 --- a/.ci/Jenkinsfile +++ b/.ci/Jenkinsfile @@ -36,11 +36,8 @@ def osFlags = [ ] def archNames = [ - '32': 'x86 (32-bit)', - 'x86': 'x86 (32-bit)', '64': 'x64 (64-bit)', 'x86_64': 'x64 (64-bit)', - 'arm32': 'ARM (32-bit)', 'arm64': 'ARM (64-bit)' ] @@ -57,11 +54,8 @@ def dynarecNames = [ ] def dynarecArchs = [ - '32': ['ODR', 'NDR'], - 'x86': ['ODR', 'NDR'], '64': ['ODR', 'NDR'], 'x86_64': ['ODR', 'NDR'], - 'arm32': ['NDR'], 'arm64': ['NDR'], 'x86_64+arm64': ['ODR', 'NDR'] ] diff --git a/.ci/build.sh b/.ci/build.sh index e62bdd0be..e18aa4837 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -325,9 +325,7 @@ echo [-] Building [$package_name] for [$arch] with flags [$cmake_flags] toolchain_prefix=flags-gcc is_mac && toolchain_prefix=llvm-macos case $arch in - 32 | x86) toolchain="$toolchain_prefix-i686";; 64 | x86_64*) toolchain="$toolchain_prefix-x86_64";; - ARM32 | arm32) toolchain="$toolchain_prefix-armv7";; ARM64 | arm64) toolchain="$toolchain_prefix-aarch64";; *) toolchain="$toolchain_prefix-$arch";; esac @@ -670,9 +668,7 @@ then else # Determine Debian architecture. case $arch in - x86) arch_deb="i386";; x86_64) arch_deb="amd64";; - arm32) arch_deb="armhf";; *) arch_deb="$arch";; esac grep -q " bullseye " /etc/apt/sources.list || echo [!] WARNING: System not running the expected Debian version @@ -710,15 +706,12 @@ else # Determine toolchain architecture triplet. case $arch in - x86) arch_triplet="i686-linux-gnu";; - arm32) arch_triplet="arm-linux-gnueabihf";; arm64) arch_triplet="aarch64-linux-gnu";; *) arch_triplet="$arch-linux-gnu";; esac # Determine library directory name for this architecture. case $arch in - x86) libdir="i386-linux-gnu";; *) libdir="$arch_triplet";; esac @@ -791,9 +784,7 @@ rm -rf build # Add ARCH to skip the arch_detect process. case $arch in - 32 | x86) cmake_flags_extra="$cmake_flags_extra -D ARCH=i386";; 64 | x86_64*) cmake_flags_extra="$cmake_flags_extra -D ARCH=x86_64";; - ARM32 | arm32) cmake_flags_extra="$cmake_flags_extra -D ARCH=arm -D NEW_DYNAREC=ON";; ARM64 | arm64) cmake_flags_extra="$cmake_flags_extra -D ARCH=arm64 -D NEW_DYNAREC=ON";; *) cmake_flags_extra="$cmake_flags_extra -D \"ARCH=$arch\"";; esac @@ -1185,8 +1176,6 @@ then else # Determine AppImage runtime architecture. case $arch in - x86) arch_appimage="i686";; - arm32) arch_appimage="armhf";; arm64) arch_appimage="aarch64";; *) arch_appimage="$arch";; esac diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index d805d84a2..785f87a4a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -52,9 +52,6 @@ body: - macOS - Universal (Intel and Apple Silicon) - Linux - x64 (64-bit) - Linux - ARM (64-bit) - - Windows - x86 (32-bit) - - Linux - ARM (32-bit) - - Linux - x86 (32-bit) validations: required: true - type: checkboxes diff --git a/CMakeLists.txt b/CMakeLists.txt index 90fcc1c0b..127f0e53c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ option(DISCORD "Discord Rich Presence support" option(DEBUGREGS486 "Enable debug register opeartion on 486+ CPUs" OFF) option(LIBASAN "Enable compilation with the addresss sanitizer" OFF) -if((ARCH STREQUAL "arm64") OR (ARCH STREQUAL "arm")) +if((ARCH STREQUAL "arm64")) set(NEW_DYNAREC ON) else() option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF) diff --git a/cmake/flags-gcc-armv7.cmake b/cmake/flags-gcc-armv7.cmake deleted file mode 100644 index 070e5e52a..000000000 --- a/cmake/flags-gcc-armv7.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running 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 toolchain file defining GCC compiler flags -# for ARMv7 targets. -# -# Authors: David Hrdlička, -# -# Copyright 2021 David Hrdlička. -# - -string(APPEND CMAKE_C_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") -string(APPEND CMAKE_CXX_FLAGS_INIT " -march=armv7-a+fp -mfloat-abi=hard") - -include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/cmake/flags-gcc-i686.cmake b/cmake/flags-gcc-i686.cmake deleted file mode 100644 index 3b3d72a16..000000000 --- a/cmake/flags-gcc-i686.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running 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 toolchain file defining GCC compiler flags -# for 32-bit x86 targets. -# -# Authors: David Hrdlička, -# -# Copyright 2021 David Hrdlička. -# - -string(APPEND CMAKE_C_FLAGS_INIT " -m32 -march=i686 -msse2 -mfpmath=sse -mstackrealign") -string(APPEND CMAKE_CXX_FLAGS_INIT " -m32 -march=i686 -msse2 -mfpmath=sse -mstackrealign") - -include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc.cmake) diff --git a/cmake/llvm-win32-i686.cmake b/cmake/llvm-win32-i686.cmake deleted file mode 100644 index b69771407..000000000 --- a/cmake/llvm-win32-i686.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running 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 toolchain file for Clang on Windows builds (x86 target). -# -# Authors: David Hrdlička, -# -# Copyright 2021 David Hrdlička. -# - -include(${CMAKE_CURRENT_LIST_DIR}/flags-gcc-i686.cmake) - -# Use the GCC-compatible Clang executables in order to use our flags -set(CMAKE_C_COMPILER clang) -set(CMAKE_CXX_COMPILER clang++) - -# `llvm-rc` is barely usable as of LLVM 13, using MS' rc.exe for now -set(CMAKE_RC_COMPILER rc) - -set(CMAKE_C_COMPILER_TARGET i686-pc-windows-msvc) -set(CMAKE_CXX_COMPILER_TARGET i686-pc-windows-msvc) - -set(CMAKE_SYSTEM_PROCESSOR X86) - -# TODO: set the vcpkg target triplet perhaps? diff --git a/debian/control b/debian/control index a11e2af48..64afafb0d 100644 --- a/debian/control +++ b/debian/control @@ -25,10 +25,9 @@ Homepage: https://86box.net/ Rules-Requires-Root: no Package: 86box -Architecture: amd64 armhf arm64 i386 +Architecture: amd64 arm64 Depends: ${shlibs:Depends}, ${misc:Depends}, - sse2-support [i386] Recommends: libpcap0.8-dev Description: An emulator for classic IBM PC clones 86Box is a low level x86 emulator that runs older operating systems and software diff --git a/debian/rules b/debian/rules index 1ee4be4ed..bd04bd9f4 100644 --- a/debian/rules +++ b/debian/rules @@ -5,20 +5,12 @@ 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 +ifeq ($(ARCH), $(filter $(ARCH), amd64)) + NDR=off + TOOLCHAIN=cmake/flags-gcc-x86_64.cmake else NDR=on - ifeq ($(ARCH),armhf) - TOOLCHAIN=cmake/flags-gcc-armv7.cmake - else - TOOLCHAIN=cmake/flags-gcc-aarch64.cmake - endif + TOOLCHAIN=cmake/flags-gcc-aarch64.cmake endif %: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b13071241..166320061 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -135,14 +135,6 @@ if(HAIKU) target_link_libraries(86Box be) endif() -if(WIN32 AND ARCH STREQUAL "i386") - if(MINGW) - target_link_options(86Box PRIVATE "LINKER:--large-address-aware") - else() - target_link_options(86Box PRIVATE "LINKER:/LARGEADDRESSAWARE") - endif() -endif() - if(STATIC_BUILD) if(MINGW OR UNIX) target_link_options(86Box PRIVATE "-static") diff --git a/src/arch_detect.c b/src/arch_detect.c index 42a7d29bf..442a44bae 100644 --- a/src/arch_detect.c +++ b/src/arch_detect.c @@ -19,8 +19,6 @@ # error ARCH arm #elif defined(__aarch64__) || defined(_M_ARM64) # error ARCH arm64 -#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) -# error ARCH i386 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) # error ARCH x86_64 #endif diff --git a/src/codegen/CMakeLists.txt b/src/codegen/CMakeLists.txt index 3d000c98d..e35d7c64f 100644 --- a/src/codegen/CMakeLists.txt +++ b/src/codegen/CMakeLists.txt @@ -10,9 +10,11 @@ # # Authors: David Hrdlička, # Jasmine Iwanek, +# Connor Hyde, # # Copyright 2020-2021 David Hrdlička. # Copyright 2024 Jasmine Iwanek. +# Copyright 2025 Connor Hyde / starfrost # if(DYNAREC) @@ -21,19 +23,15 @@ if(DYNAREC) codegen_ops.c ) - if(ARCH STREQUAL "i386") - target_sources(dynarec PRIVATE - codegen_x86.c - codegen_accumulate_x86.c - ) - elseif(ARCH STREQUAL "x86_64") + + if(ARCH STREQUAL "x86_64") target_sources(dynarec PRIVATE codegen_x86-64.c codegen_accumulate_x86-64.c ) else() message(SEND_ERROR - "Dynarec is incompatible with target platform ${ARCH}") + "Old dynarec is incompatible with target platform ${ARCH}") endif() target_link_libraries(86Box dynarec cgt) diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index d020fc57f..47ea2bec6 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -42,8 +42,6 @@ #ifdef __amd64__ # include "codegen_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 -# include "codegen_x86.h" #else # error Dynamic recompiler not implemented on your platform #endif diff --git a/src/codegen/codegen_accumulate_x86.c b/src/codegen/codegen_accumulate_x86.c deleted file mode 100644 index 8d56c4c14..000000000 --- a/src/codegen/codegen_accumulate_x86.c +++ /dev/null @@ -1,66 +0,0 @@ -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> - -#include "codegen.h" -#include "codegen_accumulate.h" - -static struct -{ - int count; - uintptr_t dest_reg; -} acc_regs[] = { - [ACCREG_cycles] = {0, (uintptr_t) & (cycles)} -}; - -void -codegen_accumulate(int acc_reg, int 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); - } - } -#endif -} - -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); - } - - acc_regs[0].count = 0; -} - -void -codegen_accumulate_reset(void) -{ - acc_regs[0].count = 0; -} diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index c8e258e78..ec7e94742 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -18,13 +18,8 @@ #include "cpu.h" #include "codegen.h" #include "codegen_ops.h" - -#if defined __amd64__ || defined _M_X64 -# include "codegen_ops_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -# include "codegen_ops_x86.h" -#endif - +// Old dynarec now x86-64 only +#include "codegen_ops_x86-64.h" #include "codegen_ops_arith.h" #include "codegen_ops_fpu.h" #include "codegen_ops_jump.h" diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h deleted file mode 100644 index 3fbefdeaa..000000000 --- a/src/codegen/codegen_ops_x86.h +++ /dev/null @@ -1,3935 +0,0 @@ -/*Register allocation : - EBX, ECX, EDX - emulated registers - EAX - work register, EA storage - ESI, EDI - work registers - EBP - points at emulated register array -*/ -#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(void) -{ - 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; -} -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; - } - - 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) -{ - addbyte(0xC6); /*MOVB [addr],val*/ - addbyte(0x05); - addlong(addr); - addbyte(val); -} -static __inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x05); - addlong(addr); - 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) -{ - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte((uint8_t) cpu_state_offset(regs[reg & 7].l)); - addlong(val); -} - -static __inline int -LOAD_REG_B(int reg) -{ - 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; -} -static __inline int -LOAD_REG_W(int reg) -{ - 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; -} -static __inline int -LOAD_REG_L(int reg) -{ - 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; -} - -static __inline int -LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0x66); /*MOVL host_reg,[reg]*/ - addbyte(0x8b); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t) addr); - - 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_REG_IMM(uint32_t imm) -{ - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; - - addbyte(0xc7); /*MOVL host_reg, imm*/ - addbyte(0xc0 | host_reg); - addlong(imm); - - return host_reg; -} - -static __inline int -LOAD_HOST_REG(int host_reg) -{ - 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_B_RELEASE(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; -} -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((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); - } -} -#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) -{ - 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) -{ - 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) -{ - 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) -{ - 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 & 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); - } -} - -#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) -{ - 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) -{ - 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) -{ - AND_HOST_REG_B(dst_reg, src_reg); - - return dst_reg; -} -static __inline int -TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static __inline int -TEST_HOST_REG_L(int dst_reg, int src_reg) -{ - AND_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static __inline int -TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - AND_HOST_REG_IMM(host_reg, imm); - - 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) -{ - 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) -{ - 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) -{ - addbyte(0xf6); - addbyte(0xd8 | reg); -} -static __inline void -NEG_HOST_REG_W(int reg) -{ - addbyte(0x66); - addbyte(0xf7); - addbyte(0xd8 | reg); -} -static __inline void -NEG_HOST_REG_L(int reg) -{ - addbyte(0xf7); - addbyte(0xd8 | 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)); -} -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)); -} -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)); -} -static __inline void -SUB_HOST_REG_IMM_B(int host_reg, uint8_t 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); - } else { - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addlong(imm); - } -} - -static __inline void -INC_HOST_REG_W(int host_reg) -{ - addbyte(0x66); /*INCW host_reg*/ - addbyte(0x40 | host_reg); -} -static __inline void -INC_HOST_REG(int host_reg) -{ - addbyte(0x40 | host_reg); /*DECL host_reg*/ -} -static __inline void -DEC_HOST_REG_W(int host_reg) -{ - addbyte(0x66); /*DECW host_reg*/ - addbyte(0x48 | host_reg); -} -static __inline void -DEC_HOST_REG(int host_reg) -{ - addbyte(0x48 | host_reg); /*DECL host_reg*/ -} - -static __inline int -CMP_HOST_REG_B(int dst_reg, int src_reg) -{ - SUB_HOST_REG_B(dst_reg, src_reg); - - return dst_reg; -} -static __inline int -CMP_HOST_REG_W(int dst_reg, int src_reg) -{ - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static __inline int -CMP_HOST_REG_L(int dst_reg, int src_reg) -{ - SUB_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static __inline int -CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - 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) -{ - 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) -{ - SUB_HOST_REG_IMM(host_reg, imm); - - 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) -{ - 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) -{ - 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) -{ - 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) -{ - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static __inline void -SHL_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHL reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static __inline void -SHL_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); -} -static __inline void -SHR_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static __inline void -SHR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static __inline void -SHR_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); -} -static __inline void -SAR_B_IMM(int reg, int count) -{ - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} -static __inline void -SAR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SAR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} -static __inline void -SAR_L_IMM(int reg, int count) -{ - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); -} - -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; - - 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; -} -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; - - 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; -} -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; - - 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, int op_32) -{ - 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); - if (!(op_32 & 0x200)) { - addbyte(0x25); /* AND EAX, ffffh */ - addbyte(0xff); - addbyte(0xff); - addbyte(0x00); - addbyte(0x00); - } - 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_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 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_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 ((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_EA_B_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_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_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 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 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_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; - } - addbyte(0x25); /*ANDL EAX, 0xffff*/ - addlong(0xffff); - - 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) -{ - uint32_t new_eaaddr; - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - - 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)++; - 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); - 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); - 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 ) -{ - 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)); -} - -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; - - 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); - 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(void) -{ - if (codegen_fpu_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)); - - 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(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(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(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(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(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 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 -#define FPU_DIV 0x30 -#define FPU_DIVR 0x38 -#define FPU_MUL 0x08 -#define FPU_SUB 0x20 -#define FPU_SUBR 0x28 - -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)); - } -} -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)); - } - } 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) -{ - 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) -{ - 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) -{ - 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(0x80); /*AND tag[0][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[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(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)); - } -} -#endif - -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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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(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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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(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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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(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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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) -{ - 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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((~(FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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((FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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(void) -{ - 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); - 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 int -ZERO_EXTEND_W_B(int reg) -{ - 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; -} - -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(void) -{ - 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(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; -} - -extern int mmx_ebx_ecx_loaded; - -static __inline int -LOAD_MMX_D(int guest_reg) -{ - 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])); - - return host_reg; -} -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; - } - - 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) -{ - 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)); - - return dst_reg; -} - -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; - - 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; -} - -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])); -} -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])); -} -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)); -} - -#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); \ - } - -// clang-format off -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(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(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(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(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); -MMX_x86_OP(PMADDWD, 0xf5); -// clang-format on - -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); -} -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); -} -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); -} -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); -} -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); -} -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); -} - -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); -} -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); -} -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); -} - -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); -} -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); -} -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); -} - -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); -} -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); -} -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); -} - -static __inline void -SAVE_EA(void) -{ - addbyte(0x89); /*MOV [ESP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); -} -static __inline void -LOAD_EA(void) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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_x86.c b/src/codegen/codegen_x86.c deleted file mode 100644 index e0b9b633a..000000000 --- a/src/codegen/codegen_x86.c +++ /dev/null @@ -1,2183 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running 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. - * - * Dynamic Recompiler for Intel 32-bit systems. - * - * - * - * Authors: Fred N. van Kempen, - * Sarah Walker, - * Miran Grca, - * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2008-2018 Sarah Walker. - * 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 - * 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. - */ -#if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 - -# include -# include -# include -# include -# include -# include <86box/86box.h> -# include <86box/plat.h> -# include "cpu.h" -# include <86box/mem.h> -# include "x86.h" -# include "x86_flags.h" -# include "x86_ops.h" -# include "x86seg_common.h" -# include "x86seg.h" -# include "x87_sf.h" -# include "x87.h" -/*ex*/ -# include <86box/nmi.h> -# include <86box/pic.h> - -# include "386_common.h" - -# include "codegen.h" -# include "codegen_accumulate.h" -# include "codegen_ops.h" -# include "codegen_ops_x86.h" - -int codegen_flat_ds; -int 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; -codeblock_t **codeblock_hash; - -int block_current = 0; -static int block_num; -int block_pos; - -uint32_t codegen_endpc; - -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 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; - -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(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 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(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); /*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(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) -{ - codeblock = plat_mmap((BLOCK_SIZE + 1) * sizeof(codeblock_t), 1); - 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; - } - } -} - -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 */ - 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; -} - -// clang-format off -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*/ - 1, 1, 1, 1, 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, 1, 1, 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*/ - 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 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*/ -}; -// clang-format on - -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); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; -} - -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; - (*op_pc)++; - - 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; -} - -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 in_lock = 0; - int c; - uint32_t op87 = 0x00000000; - - 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 = fpu_softfloat ? recomp_opcodes_0f_no_mmx : 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: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = fpu_softfloat ? NULL : 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: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = fpu_softfloat ? NULL : 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: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op87 = (op87 & 0xf800) | ((opcode & 0x07) << 8) | (fetchdat & 0xff); - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - in_lock = 1; - 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_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 (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 (op87 != 0x0000) { - STORE_IMM_ADDR_L((uintptr_t) &x87_op, op87); - } - - if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) - goto codegen_skip; - - 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(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 - - return; - } - } - -codegen_skip: - if (in_lock && ((opcode == 0x90) || (opcode == 0xec))) - /* This is always ILLEGAL. */ - op = x86_dynarec_opcodes_3DNOW[0xff]; - else - 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(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); - } - - 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]))); - - codegen_block_ins++; - - block->ins++; - -# ifdef CHECK_INT - /* Check for interrupts. */ - addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &pic_pending); -# 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])); - - codegen_endpc = (cs + cpu_state.pc) + 8; -} - -#endif diff --git a/src/codegen/codegen_x86.h b/src/codegen/codegen_x86.h deleted file mode 100644 index d6842eec1..000000000 --- a/src/codegen/codegen_x86.h +++ /dev/null @@ -1,45 +0,0 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 - -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff - -#define HASH(l) ((l) &0x1ffff) - -#define BLOCK_EXIT_OFFSET 0x7f0 -#ifdef OLD_GPF -# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) -#else -# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14) -#endif - -#define BLOCK_MAX 1720 - -enum { - OP_RET = 0xc3 -}; - -#define NR_HOST_REGS 4 -extern int host_reg_mapping[NR_HOST_REGS]; -#define NR_HOST_XMM_REGS 8 -extern int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; - -extern uint32_t mem_load_addr_ea_b; -extern uint32_t mem_load_addr_ea_w; -extern uint32_t mem_load_addr_ea_l; -extern uint32_t mem_load_addr_ea_q; -extern uint32_t mem_store_addr_ea_b; -extern uint32_t mem_store_addr_ea_w; -extern uint32_t mem_store_addr_ea_l; -extern uint32_t mem_store_addr_ea_q; - -extern uint32_t mem_load_addr_ea_b_no_abrt; -extern uint32_t mem_store_addr_ea_b_no_abrt; -extern uint32_t mem_load_addr_ea_w_no_abrt; -extern uint32_t mem_store_addr_ea_w_no_abrt; -extern uint32_t mem_load_addr_ea_l_no_abrt; -extern uint32_t mem_store_addr_ea_l_no_abrt; -extern uint32_t mem_check_write; -extern uint32_t mem_check_write_w; -extern uint32_t mem_check_write_l; diff --git a/src/codegen_new/CMakeLists.txt b/src/codegen_new/CMakeLists.txt index cee7d5cb9..75497d72e 100644 --- a/src/codegen_new/CMakeLists.txt +++ b/src/codegen_new/CMakeLists.txt @@ -46,15 +46,7 @@ if(DYNAREC) codegen_reg.c ) - if(ARCH STREQUAL "i386") - target_sources(dynarec PRIVATE - codegen_backend_x86.c - codegen_backend_x86_ops.c - codegen_backend_x86_ops_fpu.c - codegen_backend_x86_ops_sse.c - codegen_backend_x86_uops.c - ) - elseif(ARCH STREQUAL "x86_64") + if(ARCH STREQUAL "x86_64") target_sources(dynarec PRIVATE codegen_backend_x86-64.c codegen_backend_x86-64_ops.c @@ -68,12 +60,6 @@ if(DYNAREC) codegen_backend_arm64_uops.c codegen_backend_arm64_imm.c ) - elseif(ARCH STREQUAL "arm") - target_sources(dynarec PRIVATE - codegen_backend_arm.c - codegen_backend_arm_ops.c - codegen_backend_arm_uops.c - ) else() message(SEND_ERROR "Dynarec is incompatible with target platform ${ARCH}") diff --git a/src/codegen_new/codegen_allocator.c b/src/codegen_new/codegen_allocator.c index 3cdb731b9..4719dfc39 100644 --- a/src/codegen_new/codegen_allocator.c +++ b/src/codegen_new/codegen_allocator.c @@ -108,7 +108,7 @@ codeblock_allocator_get_ptr(mem_block_t *block) void codegen_allocator_clean_blocks(UNUSED(struct mem_block_t *block)) { -#if defined __ARM_EABI__ || defined _ARM_ || defined __aarch64__ || defined _M_ARM || defined _M_ARM64 +#if defined __ARM_EABI__ || defined __aarch64__ || defined _M_ARM64 while (1) { # ifndef _MSC_VER __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); diff --git a/src/codegen_new/codegen_allocator.h b/src/codegen_new/codegen_allocator.h index 21d4dbb0c..a8a8b3dfb 100644 --- a/src/codegen_new/codegen_allocator.h +++ b/src/codegen_new/codegen_allocator.h @@ -11,13 +11,11 @@ are chained together by jump instructions. Due to the chaining, the total memory size is limited by the range of a jump - 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 -#else -# define MEM_BLOCK_NR 131072 -#endif + instruction. ARMv8 is limited to +/- 128 MB, x86 to + +/- 2GB. It was 32 MB on ARMv7 before we removed it*/ + +#define MEM_BLOCK_NR 131072 + #define MEM_BLOCK_MASK (MEM_BLOCK_NR - 1) #define MEM_BLOCK_SIZE 0x3c0 diff --git a/src/codegen_new/codegen_backend.h b/src/codegen_new/codegen_backend.h index 901b5e9d9..2952e86ea 100644 --- a/src/codegen_new/codegen_backend.h +++ b/src/codegen_new/codegen_backend.h @@ -3,14 +3,10 @@ #if defined __amd64__ || defined _M_X64 # include "codegen_backend_x86-64.h" -#elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -# include "codegen_backend_x86.h" -#elif defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -# include "codegen_backend_arm.h" #elif defined __aarch64__ || defined _M_ARM64 # include "codegen_backend_arm64.h" #else -# error Dynamic recompiler not implemented on your platform +# error New dynamic recompiler not implemented on your platform #endif void codegen_backend_init(void); diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c deleted file mode 100644 index 9c480dccf..000000000 --- a/src/codegen_new/codegen_backend_arm.c +++ /dev/null @@ -1,373 +0,0 @@ -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM - -# 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 "x86seg_common.h" -# include "x86seg.h" -# include "x87_sf.h" -# include "x87.h" - -# 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; -void *codegen_mem_load_long; -void *codegen_mem_load_quad; -void *codegen_mem_load_single; -void *codegen_mem_load_double; - -void *codegen_mem_store_byte; -void *codegen_mem_store_word; -void *codegen_mem_store_long; -void *codegen_mem_store_quad; -void *codegen_mem_store_single; -void *codegen_mem_store_double; - -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_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) -{ - 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); - - *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) -{ - 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); - - *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) -{ - 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); -} - -/*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) - -static void -build_fp_round_routine(codeblock_t *block) -{ - uint32_t *jump_table; - - 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); - - 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_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_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) -{ - codeblock_t *block; - - 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 *)); - - for (int 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]); -# if 0 - pclog("block_pos=%i\n", block_pos); -# endif - - 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_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; -# if 0 - fatal("block_pos=%i\n", block_pos); -# endif - 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) -{ - 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) -{ - block_pos = BLOCK_START; - - /*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); - } -} - -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); - - 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 deleted file mode 100644 index a3e236d4e..000000000 --- a/src/codegen_new/codegen_backend_arm.h +++ /dev/null @@ -1,24 +0,0 @@ -#include "codegen_backend_arm_defs.h" - -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 - -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff - -#define HASH(l) ((l) &0x1ffff) - -#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); -void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); -void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm); -void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); -void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); - -void host_arm_call(codeblock_t *block, void *dst_addr); -void host_arm_nop(codeblock_t *block); - -void codegen_alloc(codeblock_t *block, int size); diff --git a/src/codegen_new/codegen_backend_arm_defs.h b/src/codegen_new/codegen_backend_arm_defs.h deleted file mode 100644 index 745854429..000000000 --- a/src/codegen_new/codegen_backend_arm_defs.h +++ /dev/null @@ -1,88 +0,0 @@ -#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_CPUSTATE REG_R10 - -#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_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_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_FP_REGS 8 - -extern void *codegen_mem_load_byte; -extern void *codegen_mem_load_word; -extern void *codegen_mem_load_long; -extern void *codegen_mem_load_quad; -extern void *codegen_mem_load_single; -extern void *codegen_mem_load_double; - -extern void *codegen_mem_store_byte; -extern void *codegen_mem_store_word; -extern void *codegen_mem_store_long; -extern void *codegen_mem_store_quad; -extern void *codegen_mem_store_single; -extern void *codegen_mem_store_double; - -extern void *codegen_fp_round; - -extern void *codegen_gpf_rout; -extern void *codegen_exit_rout; diff --git a/src/codegen_new/codegen_backend_arm_ops.c b/src/codegen_new/codegen_backend_arm_ops.c deleted file mode 100644 index 3331af4e0..000000000 --- a/src/codegen_new/codegen_backend_arm_ops.c +++ /dev/null @@ -1,1398 +0,0 @@ -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM - -# include -# include <86box/86box.h> -# include "cpu.h" -# include <86box/mem.h> -# include <86box/plat_unused.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 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 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 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_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_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 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 LDRH_IMM(imm) (((imm) &0xf) | (((imm) &0xf0) << 4)) -# define STRH_IMM(imm) LDRH_IMM(imm) - -# define VSHIFT_IMM(shift) ((shift) << 16) - -# define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) - -# 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) -{ - 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) -{ - /*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); - - /*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) -{ - if (block_pos >= (BLOCK_MAX - 4)) - codegen_allocate_new_block(block); -} - -void -codegen_alloc(codeblock_t *block, int size) -{ - if (block_pos >= (BLOCK_MAX - size)) - codegen_allocate_new_block(block); -} - -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 >= 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) -{ - 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; -} - -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); -# if 0 -void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -# endif -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) -{ - 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); - } -} - -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)); -} -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)); -} - -void -host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t 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); - } -} - -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)); -} -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)); -} - -void -host_arm_B(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - - 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)); -} - -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)); -} - -void -host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t 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); - } -} -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)); -} -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)); -} - -void -host_arm_BL(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - - 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)); -} -void -host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - - 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)); -} -void -host_arm_BLX(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); -} - -uint32_t * -host_arm_BCC_(codeblock_t *block) -{ - codegen_addlong(block, COND_CC | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BCS_(codeblock_t *block) -{ - codegen_addlong(block, COND_CS | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BEQ_(codeblock_t *block) -{ - codegen_addlong(block, COND_EQ | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BGE_(codeblock_t *block) -{ - codegen_addlong(block, COND_GE | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BGT_(codeblock_t *block) -{ - codegen_addlong(block, COND_GT | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BHI_(codeblock_t *block) -{ - codegen_addlong(block, COND_HI | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BLE_(codeblock_t *block) -{ - codegen_addlong(block, COND_LE | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BLS_(codeblock_t *block) -{ - codegen_addlong(block, COND_LS | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BLT_(codeblock_t *block) -{ - codegen_addlong(block, COND_LT | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BMI_(codeblock_t *block) -{ - codegen_addlong(block, COND_MI | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BNE_(codeblock_t *block) -{ - codegen_addlong(block, COND_NE | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BPL_(codeblock_t *block) -{ - codegen_addlong(block, COND_PL | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BVC_(codeblock_t *block) -{ - codegen_addlong(block, COND_VC | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} -uint32_t * -host_arm_BVS_(codeblock_t *block) -{ - codegen_addlong(block, COND_VS | OPCODE_B); - - return (uint32_t *) &block_write_data[block_pos - 4]; -} - -void -host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - - 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); - - codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); -} -void -host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) -{ - uint32_t offset; - - 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); - - codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); -} - -void -host_arm_BX(codeblock_t *block, int addr_reg) -{ - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); -} - -void -host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t 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); - } -} -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)); -} - -void -host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t 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); - } -} -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)); -} - -void -host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t 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); - } -} - -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)); -} - -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); -} - -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)); -} -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)); -} -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)); -} - -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"); -} -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)); -} -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)); -} - -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)); -} -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)); -} - -void -host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t 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); - } -} - -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} - -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)); -} -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)); -} - -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)); -} - -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; - - 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) -{ - 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) -{ - 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); - } -} -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)); -} -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)); -} - -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); -} - -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)); -} -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)); -} -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)); -} - -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)); -} -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)); -} - -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)); -} -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)); -} - -void -host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t 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); - } -} - -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)); -} -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)); -} - -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)); -} -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)); -} - -void -host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t 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); - } -} -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)); -} - -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)); -} - -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)); -} - -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)); -} - -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)); -} - -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)); -} - -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)); -} - -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)); -} - -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} - -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} - -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -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)); -} -void -host_arm_VMOV_F32_ONE(codeblock_t *block, int 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) -{ - codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); -} -void -host_arm_VMRS_APSR(codeblock_t *block) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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 deleted file mode 100644 index 271fbffbd..000000000 --- a/src/codegen_new/codegen_backend_arm_ops.h +++ /dev/null @@ -1,252 +0,0 @@ -#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) - -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) -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_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); - -void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); -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_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); - -void host_arm_B(codeblock_t *block, uintptr_t dest_addr); - -void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width); - -void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); -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_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); - -void host_arm_BL(codeblock_t *block, uintptr_t dest_addr); -void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr); -void host_arm_BLX(codeblock_t *block, int addr_reg); - -uint32_t *host_arm_BCC_(codeblock_t *block); -uint32_t *host_arm_BCS_(codeblock_t *block); -uint32_t *host_arm_BEQ_(codeblock_t *block); -uint32_t *host_arm_BGE_(codeblock_t *block); -uint32_t *host_arm_BGT_(codeblock_t *block); -uint32_t *host_arm_BHI_(codeblock_t *block); -uint32_t *host_arm_BLE_(codeblock_t *block); -uint32_t *host_arm_BLS_(codeblock_t *block); -uint32_t *host_arm_BLT_(codeblock_t *block); -uint32_t *host_arm_BMI_(codeblock_t *block); -uint32_t *host_arm_BNE_(codeblock_t *block); -uint32_t *host_arm_BPL_(codeblock_t *block); -uint32_t *host_arm_BVC_(codeblock_t *block); -uint32_t *host_arm_BVS_(codeblock_t *block); - -void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr); -void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr); - -void host_arm_BX(codeblock_t *block, int addr_reg); - -void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm); -void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift); - -void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm); -#define host_arm_CMP_REG(block, src_reg_n, src_reg_m) host_arm_CMP_REG_LSL(block, src_reg_n, src_reg_m, 0) -void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift); - -void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); -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_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); - -void host_arm_LDR_IMM(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); -#define host_arm_LDR_REG(block, dst_reg, addr_reg, offset_reg) host_arm_LDR_REG_LSL(block, dst_reg, addr_reg, offset_reg, 0) -void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift); - -void host_arm_LDRB_ABS(codeblock_t *block, int dst, void *p); -void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); -#define host_arm_LDRB_REG(block, dst_reg, addr_reg, offset_reg) host_arm_LDRB_REG_LSL(block, dst_reg, addr_reg, offset_reg, 0) -void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift); - -void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset); -void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg); - -void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm); -#define host_arm_MOV_REG(block, dst_reg, src_reg) host_arm_MOV_REG_LSL(block, dst_reg, src_reg, 0) -void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int 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_LSL(codeblock_t *block, int dst_reg, int src_reg, int 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_LSR(codeblock_t *block, int dst_reg, int src_reg, int 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_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift); -void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg); -void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm); -void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm); - -void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift); - -#define host_arm_NOP(block) host_arm_MOV_REG(block, REG_R0, REG_R0) - -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_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) - -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); -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_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); - -void host_arm_STR_IMM(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); -#define host_arm_STR_REG(block, src_reg, addr_reg, offset_reg) host_arm_STR_REG_LSL(block, src_reg, addr_reg, offset_reg, 0) -void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift); - -void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset); -#define host_arm_STRB_REG(block, src_reg, addr_reg, offset_reg) host_arm_STRB_REG_LSL(block, src_reg, addr_reg, offset_reg, 0) -void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift); - -void host_arm_STRH_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset); -void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg); - -void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); -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_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); - -void host_arm_SXTB(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); - -void host_arm_TST_IMM(codeblock_t *block, int src_reg1, uint32_t imm); -void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2); - -void host_arm_UADD8(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); - -void host_arm_USUB8(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); - -void host_arm_UXTB(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); - -void host_arm_VABS_D(codeblock_t *block, int dest_reg, int 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_I8(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); -void host_arm_VADD_I32(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); -void host_arm_VAND_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); -void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int 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_I8(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); -void host_arm_VCEQ_I32(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); -void host_arm_VCGT_F32(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); -void host_arm_VCGT_S16(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); - -void host_arm_VCHS_D(codeblock_t *block, int dest_reg, int src_reg); - -void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VCVT_S_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); -void host_arm_VDIV_D(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); -void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm); -void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); -void host_arm_VLDR_D(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); - -void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int 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_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high); -void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg); - -void host_arm_VMRS_APSR(codeblock_t *block); -void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg); - -void host_arm_VMAX_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); - -void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg); - -void host_arm_VMUL_D(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); -void host_arm_VMUL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); -void host_arm_VMULL_S16(codeblock_t *block, int dest_reg, int src_reg_n, int src_reg_m); - -void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg); - -void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m); - -void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg); -void host_arm_VPADDL_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); - -void host_arm_VQADD_S8(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); -void host_arm_VQADD_S16(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); -void host_arm_VQSUB_S8(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); -void host_arm_VQSUB_S16(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); - -void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg); -void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg); -void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg); - -void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHR_D_S16(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHR_D_S32(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHR_D_S64(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHR_D_U16(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHR_D_U32(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHR_D_U64(codeblock_t *block, int dest_reg, int src_reg, int shift); -void host_arm_VSHRN_32(codeblock_t *block, int dest_reg, int src_reg, int shift); - -void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg); -void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg); - -void host_arm_VSTR_D(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); -void host_arm_VSUB_D(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); -void host_arm_VSUB_S(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); -void host_arm_VSUB_I16(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); - -void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg); -void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg); -void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg); diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c deleted file mode 100644 index b186e0e3b..000000000 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ /dev/null @@ -1,3720 +0,0 @@ -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM - -# include -# include -# include <86box/86box.h> -# include "cpu.h" -# include <86box/mem.h> -# include <86box/plat_unused.h> - -# include "x86.h" -# include "x86seg_common.h" -# include "x86seg.h" -# include "x87_sf.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) -{ - 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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) -{ -# if 0 - host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); - return 0; -# endif - - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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_MOV_IMM(block, REG_ARG0, uop->imm_data); - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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, FPU_SW_C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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, FPU_SW_C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, FPU_SW_C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int 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; -} - -static int -codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(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); - if (uop->is_a16) - host_arm_AND_IMM(block, REG_R0, REG_R0, 0xffff); - 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); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int 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); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int 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); - int 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); - } 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; -} - -static int -codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_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); - - 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); - int 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_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); - int 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); - int 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); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int 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); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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; - int64_t 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); - int tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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 - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int -codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} -static int -codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - } - } 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; -} - -static int -codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} -static int -codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} -static int -codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} -static int -codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} -static int -codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} -static int -codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - return 0; -} - -static int -codegen_STORE_PTR_IMM(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_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; -} -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"); - - return 0; -} - -static int -codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - return 0; - -# if 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; -# endif -} -static int -codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - 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_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); - - 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_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); - - return 0; -} - -static int -codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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 src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - - 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_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_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) -{ - 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) -{ - 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) -{ - 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) -{ - codegen_direct_read_32(block, host_reg, 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); -} -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); -} -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); -} -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); -} -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); -} - -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"); -} -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); - } -} -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"); -} -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); -} -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); -} -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); -} -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); -} -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); -} - -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"); -} - -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"); -} -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"); -} -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); -} -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); -} -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); -} - -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"); -} -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); -} -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); -} - -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; -} -#endif diff --git a/src/codegen_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c deleted file mode 100644 index 18235e2b2..000000000 --- a/src/codegen_new/codegen_backend_x86.c +++ /dev/null @@ -1,345 +0,0 @@ -#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 "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 "x86seg_common.h" -# include "x86seg.h" - -# 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; -void *codegen_mem_load_long; -void *codegen_mem_load_quad; -void *codegen_mem_load_single; -void *codegen_mem_load_double; - -void *codegen_mem_store_byte; -void *codegen_mem_store_word; -void *codegen_mem_store_long; -void *codegen_mem_store_quad; -void *codegen_mem_store_single; -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_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) -{ - 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); - - *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) -{ - 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); - - *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) -{ - 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); -} - -void -codegen_backend_init(void) -{ - codeblock_t *block; - - 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 *)); - - for (uint32_t 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); - - 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; -} - -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); -} - -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); - } -} - -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); -} - -#endif diff --git a/src/codegen_new/codegen_backend_x86.h b/src/codegen_new/codegen_backend_x86.h deleted file mode 100644 index 646289fab..000000000 --- a/src/codegen_new/codegen_backend_x86.h +++ /dev/null @@ -1,14 +0,0 @@ -#include "codegen_backend_x86_defs.h" - -#define BLOCK_SIZE 0x10000 -#define BLOCK_MASK 0xffff -#define BLOCK_START 0 - -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff - -#define HASH(l) ((l) &0x1ffff) - -#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 deleted file mode 100644 index a86d6f309..000000000 --- a/src/codegen_new/codegen_backend_x86_defs.h +++ /dev/null @@ -1,50 +0,0 @@ -#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_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 CODEGEN_HOST_REGS 3 -#define CODEGEN_HOST_FP_REGS 6 - -extern void *codegen_mem_load_byte; -extern void *codegen_mem_load_word; -extern void *codegen_mem_load_long; -extern void *codegen_mem_load_quad; -extern void *codegen_mem_load_single; -extern void *codegen_mem_load_double; - -extern void *codegen_mem_store_byte; -extern void *codegen_mem_store_word; -extern void *codegen_mem_store_long; -extern void *codegen_mem_store_quad; -extern void *codegen_mem_store_single; -extern void *codegen_mem_store_double; - -extern void *codegen_gpf_rout; -extern void *codegen_exit_rout; - -#define STACK_ARG0 (0) -#define STACK_ARG1 (4) -#define STACK_ARG2 (8) -#define STACK_ARG3 (12) - -#endif diff --git a/src/codegen_new/codegen_backend_x86_ops.c b/src/codegen_new/codegen_backend_x86_ops.c deleted file mode 100644 index 90e59dcb0..000000000 --- a/src/codegen_new/codegen_backend_x86_ops.c +++ /dev/null @@ -1,1312 +0,0 @@ -#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 <86box/plat_unused.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_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) -{ - 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) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ -} -void -host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 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 == 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) -{ - 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, 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_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, 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_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - 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_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) -{ - 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_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) -{ - 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, 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*/ - } -} -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, 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_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, 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_POP(codeblock_t *block, int src_reg) -{ - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ -} - -void -host_x86_PUSH(codeblock_t *block, int src_reg) -{ - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ -} - -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, 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); - } -} -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, 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_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - 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_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_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, 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, 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); - } -} - -#endif diff --git a/src/codegen_new/codegen_backend_x86_ops.h b/src/codegen_new/codegen_backend_x86_ops.h deleted file mode 100644 index 0890286ef..000000000 --- a/src/codegen_new/codegen_backend_x86_ops.h +++ /dev/null @@ -1,195 +0,0 @@ -void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p); - -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_CALL(codeblock_t *block, void *p); - -void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); -void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); -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); -uint32_t *host_x86_JMP_short(codeblock_t *block); -uint32_t *host_x86_JMP_long(codeblock_t *block); - -void host_x86_JNZ(codeblock_t *block, void *p); -void host_x86_JZ(codeblock_t *block, void *p); - -uint8_t *host_x86_JNZ_short(codeblock_t *block); -uint8_t *host_x86_JS_short(codeblock_t *block); -uint8_t *host_x86_JZ_short(codeblock_t *block); - -uint32_t *host_x86_JNB_long(codeblock_t *block); -uint32_t *host_x86_JNBE_long(codeblock_t *block); -uint32_t *host_x86_JNL_long(codeblock_t *block); -uint32_t *host_x86_JNLE_long(codeblock_t *block); -uint32_t *host_x86_JNO_long(codeblock_t *block); -uint32_t *host_x86_JNS_long(codeblock_t *block); -uint32_t *host_x86_JNZ_long(codeblock_t *block); -uint32_t *host_x86_JB_long(codeblock_t *block); -uint32_t *host_x86_JBE_long(codeblock_t *block); -uint32_t *host_x86_JL_long(codeblock_t *block); -uint32_t *host_x86_JLE_long(codeblock_t *block); -uint32_t *host_x86_JO_long(codeblock_t *block); -uint32_t *host_x86_JS_long(codeblock_t *block); -uint32_t *host_x86_JZ_long(codeblock_t *block); - -void host_x86_LAHF(codeblock_t *block); - -void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg_a, uint32_t offset); -void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int 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); - -void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); -void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data); -void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data); - -void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg); -void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, 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); - -void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); - -void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); -void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int dst_reg); - -void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data); - -void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p); - -void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift); - -void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_addr, uint32_t addr, int base_reg, int idx_reg, int shift); - -void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); - -void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); -void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); - -void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); -void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); - -#define host_x86_MOV16_STACK_REG(block, offset, src_reg) host_x86_MOV16_BASE_OFFSET_REG(block, REG_ESP, offset, src_reg) - -void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data); - -void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p); -void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p); - -void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); - -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x86_POP(codeblock_t *block, int src_reg); - -void host_x86_PUSH(codeblock_t *block, int src_reg); - -void host_x86_RET(codeblock_t *block); - -void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_ROL8_CL(codeblock_t *block, int dst_reg); -void host_x86_ROL16_CL(codeblock_t *block, int dst_reg); -void host_x86_ROL32_CL(codeblock_t *block, int dst_reg); - -void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_ROR8_CL(codeblock_t *block, int dst_reg); -void host_x86_ROR16_CL(codeblock_t *block, int dst_reg); -void host_x86_ROR32_CL(codeblock_t *block, int dst_reg); - -void host_x86_SAR8_CL(codeblock_t *block, int dst_reg); -void host_x86_SAR16_CL(codeblock_t *block, int dst_reg); -void host_x86_SAR32_CL(codeblock_t *block, int dst_reg); - -void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_SHL8_CL(codeblock_t *block, int dst_reg); -void host_x86_SHL16_CL(codeblock_t *block, int dst_reg); -void host_x86_SHL32_CL(codeblock_t *block, int dst_reg); - -void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_SHR8_CL(codeblock_t *block, int dst_reg); -void host_x86_SHR16_CL(codeblock_t *block, int dst_reg); -void host_x86_SHR32_CL(codeblock_t *block, int dst_reg); - -void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); - -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUB32_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); -void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); -void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg); - -void host_x86_TEST32_REG_IMM(codeblock_t *block, int src_host_reg, uint32_t imm_data); - -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data); -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data); -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data); diff --git a/src/codegen_new/codegen_backend_x86_ops_fpu.c b/src/codegen_new/codegen_backend_x86_ops_fpu.c deleted file mode 100644 index 7f4735124..000000000 --- a/src/codegen_new/codegen_backend_x86_ops_fpu.c +++ /dev/null @@ -1,75 +0,0 @@ -#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 <86box/plat_unused.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) -{ - 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) -{ - 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) -{ - 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); - } -} -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]*/ - } -} -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]*/ - } -} - -#endif diff --git a/src/codegen_new/codegen_backend_x86_ops_fpu.h b/src/codegen_new/codegen_backend_x86_ops_fpu.h deleted file mode 100644 index e4479ae72..000000000 --- a/src/codegen_new/codegen_backend_x86_ops_fpu.h +++ /dev/null @@ -1,5 +0,0 @@ -void host_x87_FILDq_BASE(codeblock_t *block, int base_reg); -void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg); -void host_x87_FLDCW(codeblock_t *block, void *p); -void host_x87_FLDd_BASE(codeblock_t *block, int base_reg); -void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg); diff --git a/src/codegen_new/codegen_backend_x86_ops_helpers.h b/src/codegen_new/codegen_backend_x86_ops_helpers.h deleted file mode 100644 index f0da3ff64..000000000 --- a/src/codegen_new/codegen_backend_x86_ops_helpers.h +++ /dev/null @@ -1,94 +0,0 @@ -#define JMP_LEN_BYTES 5 - -static inline void -codegen_addbyte(UNUSED(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; -} -static inline void -codegen_addbyte2(UNUSED(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; -} -static inline void -codegen_addbyte3(UNUSED(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; -} -static inline void -codegen_addbyte4(UNUSED(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; -} - -static inline void -codegen_addword(UNUSED(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; -} - -static inline void -codegen_addlong(UNUSED(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; -} - -static inline void -codegen_addquad(UNUSED(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; -} - -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); - - /*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; -} - -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); -} - -static inline int -is_imm8(uint32_t imm_data) -{ - 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 deleted file mode 100644 index 084e04a87..000000000 --- a/src/codegen_new/codegen_backend_x86_ops_sse.c +++ /dev/null @@ -1,630 +0,0 @@ -#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 <86box/plat_unused.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) -{ - 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) -{ - 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_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*/ -} - -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_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, 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, 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) -{ - 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_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) -{ - 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_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_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_ops_sse.h b/src/codegen_new/codegen_backend_x86_ops_sse.h deleted file mode 100644 index 0c895a605..000000000 --- a/src/codegen_new/codegen_backend_x86_ops_sse.h +++ /dev/null @@ -1,111 +0,0 @@ -void host_x86_ADDPS_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); - -#define CMPPS_EQ 0 -#define CMPPS_NLT 5 -#define CMPPS_NLE 6 -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type); - -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b); - -void host_x86_CVTDQ2PS_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); - -void host_x86_CVTSD2SI_REG_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); - -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dest_reg, int src_reg); -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dest_reg, int src_reg); -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_LDMXCSR(codeblock_t *block, void *p); - -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, 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); -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg); -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg); -void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg); - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *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); -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg); -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset); -void host_x86_MOVQ_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); -void host_x86_MINPS_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); -void host_x86_MULSD_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); -void host_x86_PACKSSDW_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); - -void host_x86_PADDB_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); -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PCMPGTD_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); -void host_x86_PMULHW_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); - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift); -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift); - -void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle); - -void host_x86_PSUBB_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); -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PSUBUSW_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); -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); - -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg); diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c deleted file mode 100644 index fad088822..000000000 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ /dev/null @@ -1,3533 +0,0 @@ -#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 <86box/plat_unused.h> - -# include "x86.h" -# include "x86_ops.h" -# include "x86seg_common.h" -# include "x86seg.h" -# include "x87_sf.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_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) - -static int -codegen_ADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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 - 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) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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 - 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) -{ - 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 - 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) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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; -} - -static int -codegen_AND_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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; -} - -static int -codegen_ANDN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); -# if 0 - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); -# endif - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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; -} - -static int -codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) -{ - host_x86_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); -# 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; -} - -static int -codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); -# if 0 - host_x86_CALL(block, codegen_debug); -# endif - - 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_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; -} - -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_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; -} -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_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; -} - -static int -codegen_CMP_JB(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - - return 0; -} - -static int -codegen_FABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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; -} -static int -codegen_FCHS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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; -} - -static int -codegen_FADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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, FPU_SW_C0 | FPU_SW_C2 | FPU_SW_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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - 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; - - 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); - 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(codeblock_t *block, uop_t *uop) -{ - host_x86_JMP(block, uop->p); - - 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(UNUSED(codeblock_t *block), UNUSED(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(UNUSED(codeblock_t *block), UNUSED(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(UNUSED(codeblock_t *block), UNUSED(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 - 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); - int 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); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int 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 (uop->is_a16) { - host_x86_AND32_REG_IMM(block, REG_ESI, 0x0000ffff); - } - } - 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); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int 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); - int seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int 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); - int 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); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int 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); - int 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); - int 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); - int 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); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int 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); - int addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_64_reg = HOST_REG_GET(uop->src_reg_b_real); - int tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - int 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(UNUSED(codeblock_t *block), UNUSED(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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int 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); - int src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - int 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); - int 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) -{ - host_x86_MOV8_REG_ABS(block, host_reg, p); -} -void -codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) -{ - host_x86_MOV16_REG_ABS(block, host_reg, p); -} -void -codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) -{ - host_x86_MOV32_REG_ABS(block, host_reg, p); -} -void -codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) -{ - codegen_direct_read_32(block, host_reg, p); -} -void -codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) -{ - host_x86_MOVQ_XREG_ABS(block, host_reg, p); -} -void -codegen_direct_read_double(codeblock_t *block, int host_reg, void *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) -{ - 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); -} -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); - - 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) -{ - 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); -} - -void -codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) -{ - host_x86_MOV8_ABS_REG(block, p, host_reg); -} -void -codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) -{ - host_x86_MOV16_ABS_REG(block, p, host_reg); -} -void -codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) -{ - host_x86_MOV32_ABS_REG(block, p, host_reg); -} -void -codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) -{ - host_x86_MOVQ_ABS_XREG(block, p, host_reg); -} -void -codegen_direct_write_double(codeblock_t *block, void *p, int 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) -{ - 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); -} -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); - - 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) -{ - 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); -} - -void -codegen_direct_write_ptr(codeblock_t *block, void *p, int 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); -} - -void -codegen_set_jump_dest(UNUSED(codeblock_t *block), void *p) -{ - *(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) -{ - host_x86_MOV8_ABS_IMM(block, p, 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); -} -void -codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t 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) -{ - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); -} - -#endif diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 47f3e7f5c..5f78ef2ef 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -388,11 +388,11 @@ typedef struct { uint32_t old_fp_control; uint32_t new_fp_control; # endif -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 +# if defined _M_IX86 uint16_t old_fp_control2; uint16_t new_fp_control2; # endif -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined __amd64__ || defined _M_X64 +# if defined __amd64__ || defined _M_X64 uint32_t trunc_fp_control; # endif #else diff --git a/src/device/mouse_wacom_tablet.c b/src/device/mouse_wacom_tablet.c index 3b50882ab..99596c9f4 100644 --- a/src/device/mouse_wacom_tablet.c +++ b/src/device/mouse_wacom_tablet.c @@ -106,7 +106,7 @@ typedef struct mouse_wacom_t { int last_abs_y; /* Suppressed/Increment Mode. */ union { uint32_t settings; /* Settings DWORD */ - /* We don't target any architectures except x86/x64/ARM32/ARM64. + /* We don't target any architectures except x64/ARM64. (The ABIs for those are explicit in little-endian bit ordering) */ struct settings_bits { uint8_t remote_mode : 1; diff --git a/src/floppy/lzf/lzfP.h b/src/floppy/lzf/lzfP.h index 6bb81d562..1e8279ae4 100644 --- a/src/floppy/lzf/lzfP.h +++ b/src/floppy/lzf/lzfP.h @@ -79,7 +79,7 @@ * Unconditionally aligning does not cost very much, so do it if unsure */ #ifndef STRICT_ALIGN -# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) +# define STRICT_ALIGN !(defined (__amd64)) #endif /* diff --git a/src/include/86box/vid_voodoo_render.h b/src/include/86box/vid_voodoo_render.h index e88d21dd5..649fb6ad6 100644 --- a/src/include/86box/vid_voodoo_render.h +++ b/src/include/86box/vid_voodoo_render.h @@ -1,7 +1,7 @@ #ifndef VIDEO_VOODOO_RENDER_H #define VIDEO_VOODOO_RENDER_H -#if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined __amd64__ || defined _M_X64) +#if !(defined __amd64__ || defined _M_X64) # define NO_CODEGEN #endif diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 16906ec41..e71497698 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -72,7 +72,7 @@ Collection of ROMs for use with 86Box. %autosetup -p1 -a1 %build -%ifarch i386 x86_64 +%ifarch x86_64 %cmake -DRELEASE=on %else %ifarch arm aarch64 diff --git a/src/unix/unix.c b/src/unix/unix.c index 4f3990590..70cf5b87c 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -1038,12 +1038,8 @@ monitor_thread(UNUSED(void *param)) # define EMU_GIT_HASH "0000000" # endif -# if defined(__arm__) || defined(__TARGET_ARCH_ARM) -# define ARCH_STR "arm" -# elif defined(__aarch64__) || defined(_M_ARM64) +# if defined(__aarch64__) || defined(_M_ARM64) # define ARCH_STR "arm64" -# elif defined(__i386) || defined(__i386__) || defined(_M_IX86) -# define ARCH_STR "i386" # elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) # define ARCH_STR "x86_64" # else diff --git a/src/utils/random.c b/src/utils/random.c index 3f5fed1b9..880e3add3 100644 --- a/src/utils/random.c +++ b/src/utils/random.c @@ -19,7 +19,7 @@ #include #include <86box/random.h> -#if !(defined(__i386__) || defined(__x86_64__)) +#if ! defined(__x86_64__)) # include #endif diff --git a/src/video/vid_voodoo_render.c b/src/video/vid_voodoo_render.c index cc52fc61a..6bd80ec08 100644 --- a/src/video/vid_voodoo_render.c +++ b/src/video/vid_voodoo_render.c @@ -655,9 +655,7 @@ voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_sta state->tex_a[0] ^= 0xff; } -#if (defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86) && !(defined __amd64__ || defined _M_X64) -# include <86box/vid_voodoo_codegen_x86.h> -#elif (defined __amd64__ || defined _M_X64) +#if (defined __amd64__ || defined _M_X64) # include <86box/vid_voodoo_codegen_x86-64.h> #else int voodoo_recomp = 0;