From 043e2b6baa6d8c2d1abecbd9006a38d4c463b889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:35:56 +0200 Subject: [PATCH 001/138] Rewrite custom EDID loading --- src/include/86box/vid_ddc.h | 7 +- src/qt/qt_settingsdisplay.cpp | 7 +- src/utils/CMakeLists.txt | 1 - src/utils/edid_parse.cpp | 119 ------------------------ src/video/CMakeLists.txt | 1 + src/video/vid_ddc.c | 168 +++++++++++++--------------------- src/video/vid_ddc_custom.c | 110 ++++++++++++++++++++++ 7 files changed, 182 insertions(+), 231 deletions(-) delete mode 100644 src/utils/edid_parse.cpp create mode 100644 src/video/vid_ddc_custom.c diff --git a/src/include/86box/vid_ddc.h b/src/include/86box/vid_ddc.h index 8d68d0adf..32c8e88c5 100644 --- a/src/include/86box/vid_ddc.h +++ b/src/include/86box/vid_ddc.h @@ -20,8 +20,9 @@ #ifndef EMU_VID_DDC_H #define EMU_VID_DDC_H -extern void *ddc_init(void *i2c); -extern void ddc_close(void *eeprom); -extern void *ddc_create_default_edid(ssize_t* size_out); +extern void *ddc_init(void *i2c); +extern void ddc_close(void *eeprom); +extern size_t ddc_create_default_edid(uint8_t **size_out); +extern size_t ddc_load_edid(char *path, uint8_t *buf, size_t size); #endif /*EMU_VID_DDC_H*/ diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index bbe64dc00..ed9ba220c 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -23,6 +23,8 @@ #include #include +#include + extern "C" { #include <86box/86box.h> #include <86box/device.h> @@ -343,11 +345,10 @@ void SettingsDisplay::on_pushButtonExportDefault_clicked() if (!str.isEmpty()) { QFile file(str); if (file.open(QFile::WriteOnly)) { - ssize_t size = 0; - auto bytes = ddc_create_default_edid(&size); + uint8_t *bytes = nullptr; + auto size = ddc_create_default_edid(&bytes); file.write((char*)bytes, size); file.close(); } } } - diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index e4dea5d61..bcbc7aafd 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -19,7 +19,6 @@ add_library(utils OBJECT cJSON.c crc.c crc32.c - edid_parse.cpp fifo.c fifo8.c ini.c diff --git a/src/utils/edid_parse.cpp b/src/utils/edid_parse.cpp deleted file mode 100644 index 5aff4e3e6..000000000 --- a/src/utils/edid_parse.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -extern "C" -{ -#include <86box/86box.h> -#include <86box/plat.h> - -extern int ini_detect_bom(const char *fn); -extern ssize_t local_getline(char **buf, size_t *bufsiz, FILE *fp); -} - -// https://stackoverflow.com/a/64886763 -static std::vector split(const std::string str, const std::string regex_str) -{ - std::regex regexz(regex_str); - std::vector list(std::sregex_token_iterator(str.begin(), str.end(), regexz, -1), - std::sregex_token_iterator()); - return list; -} - -extern "C" -{ - bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size_out) - { - std::regex regexLib("^([a-f0-9]{32}|[a-f0-9 ]{47})$", std::regex_constants::egrep); - FILE* file = NULL; - try { - bool bom = ini_detect_bom(path); - { - // First check for "edid-decode (hex)" string. - file = plat_fopen(path, "rb"); - if (file) { - std::string str; - ssize_t size; - if (!fseek(file, 0, SEEK_END)) { - size = ftell(file); - if (size != -1) { - str.resize(size); - } - fseek(file, 0, SEEK_SET); - auto read = fread((void*)str.data(), 1, size, file); - str.resize(read); - fclose(file); - file = NULL; - - if (str.size() == 0) { - return false; - } - - if (str.find("edid-decode (hex):") == std::string::npos) { - return false; - } - } - } else { - return false; - } - } - file = plat_fopen(path, "rb"); - if (file) { - size_t size = 0; - std::string edid_decode_text; - fseek(file, 0, SEEK_END); - size = ftell(file); - fseek(file, 0, SEEK_SET); - if (bom) { - fseek(file, 3, SEEK_SET); - size -= 3; - } - edid_decode_text.resize(size); - auto err = fread((void*)edid_decode_text.data(), size, 1, file); - fclose(file); - file = NULL; - if (err == 0) { - return false; - } - std::istringstream isstream(edid_decode_text); - std::string line; - std::string edid; - while (std::getline(isstream, line)) { - if (line[line.size() - 1] == '\r') { - line.resize(line.size() - 1); - } - std::smatch matched; - if (std::regex_match(line, matched, regexLib)) { - edid.append(matched.str() + " "); - } - } - if (edid.size() >= 3) { - edid.resize(edid.size() - 1); - auto vals = split(edid, "\\s+"); - if (vals.size()) { - *size_out = vals.size(); - if (vals.size() > 256) - return false; - for (size_t i = 0; i < vals.size(); i++) { - out[i] = (uint8_t)std::strtoul(&vals[i][0], nullptr, 16); - } - return true; - } - } - } - - return false; - } catch (std::bad_alloc&) { - if (file) { - fclose(file); - file = NULL; - } - return false; - } - return false; - } -} \ No newline at end of file diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 6301956c5..4667a3b4f 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -44,6 +44,7 @@ add_library(vid OBJECT # DDC / monitor identification stuff vid_ddc.c + vid_ddc_custom.c # CARDS start here diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index 6d86a25c9..aeaba3965 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -14,7 +14,6 @@ * * Copyright 2020 RichardG. */ -#include #include #include #include @@ -130,8 +129,8 @@ typedef struct { uint8_t padding[15], checksum2; } edid_t; -void* -ddc_create_default_edid(ssize_t* size_out) +size_t +ddc_create_default_edid(uint8_t **out) { edid_t *edid = malloc(sizeof(edid_t)); memset(edid, 0, sizeof(edid_t)); @@ -226,120 +225,79 @@ ddc_create_default_edid(ssize_t* size_out) edid->checksum2 += edid_bytes[c]; edid->checksum2 = 256 - edid->checksum2; - if (size_out) - *size_out = sizeof(edid_t); - - return edid; + if (out) { + *out = edid_bytes; + } + + return sizeof(edid_t); } -extern bool parse_edid_decode_file(const char* path, uint8_t* out, ssize_t* size); +void * +ddc_init_with_custom_edid(char *edid_path, void *i2c) +{ + uint8_t buffer[384] = { 0 }; + size_t size = ddc_load_edid(edid_path, buffer, sizeof(buffer)); + + if (size > 256) { + wchar_t errmsg[2048] = { 0 }; + wchar_t path[2048] = { 0 }; + +#ifdef _WIN32 + mbstoc16s(path, monitor_edid_path, sizeof_w(path)); +#else + mbstowcs(path, monitor_edid_path, sizeof_w(path)); +#endif + swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); + ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); + + return NULL; + } else if (size == 0) { + return NULL; + } else if (size < 128) { + size = 128; + } else if (size < 256) { + size = 256; + } + + int checksum = 0; + for (int i = 0; i < 127; i++) { + checksum += buffer[i]; + } + + buffer[127] = 256 - checksum; + + if (size == 256) { + checksum = 0; + + for (int i = 128; i < 255; i++) { + checksum += buffer[i]; + } + buffer[255] = 256 - checksum; + } + + uint8_t *edid_bytes = malloc(size); + memcpy(edid_bytes, buffer, size); + + return i2c_eeprom_init(i2c, 0x50, edid_bytes, size); +} void * ddc_init(void *i2c) { - ssize_t edid_size = 0; - uint8_t* edid_bytes = NULL; - if (monitor_edid == 1 && monitor_edid_path[0]) { - FILE* file; - { - edid_bytes = calloc(1, 256); - if (parse_edid_decode_file(monitor_edid_path, edid_bytes, &edid_size) == false) { - if (edid_size > 256) { - wchar_t errmsg[2048] = { 0 }; - wchar_t path[2048] = { 0 }; + if (monitor_edid && monitor_edid_path[0]) { + void *ret = ddc_init_with_custom_edid(monitor_edid_path, i2c); -#ifdef _WIN32 - mbstoc16s(path, monitor_edid_path, sizeof_w(path)); -#else - mbstowcs(path, monitor_edid_path, sizeof_w(path)); -#endif - swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); - ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); - } - free(edid_bytes); - } else { - goto calculate_cksum; - } + if (ret) { + return ret; } - file = plat_fopen(monitor_edid_path, "rb"); - - if (!file) - goto default_init; - - if (fseek(file, 0, SEEK_END) == -1) { - fclose(file); - goto default_init; - } - - edid_size = ftell(file); - fseek(file, 0, SEEK_SET); - - if (edid_size <= 0) { - fclose(file); - goto default_init; - } - - if (edid_size > 256) { - wchar_t errmsg[2048] = { 0 }; - wchar_t path[2048] = { 0 }; - -#ifdef _WIN32 - mbstoc16s(path, monitor_edid_path, sizeof_w(path)); -#else - mbstowcs(path, monitor_edid_path, sizeof_w(path)); -#endif - swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); - ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); - fclose(file); - goto default_init; - } - - edid_bytes = calloc(1, edid_size); - if (!edid_bytes) { - fclose(file); - goto default_init; - } - - if (fread(edid_bytes, edid_size, 1, file) <= 0) { - free(edid_bytes); - fclose(file); - goto default_init; - } - - fclose(file); -calculate_cksum: - if (edid_size < 128) { - edid_bytes = realloc(edid_bytes, 128); - edid_size = 128; - } else if (edid_size < 256) { - edid_bytes = realloc(edid_bytes, 256); - edid_size = 256; - } - - { - int checksum = 0; - for (uint8_t c = 0; c < 127; c++) - checksum += edid_bytes[c]; - edid_bytes[127] = 256 - checksum; - - if (edid_size == 256) { - checksum = 0; - - for (uint8_t c = 128; c < 255; c++) { - checksum += edid_bytes[c]; - } - edid_bytes[255] = 256 - checksum; - } - } - - return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } -default_init: - edid_size = sizeof(edid_t); - edid_bytes = ddc_create_default_edid(&edid_size); + + uint8_t *edid_bytes; + size_t edid_size = ddc_generate_default_edid(&edid_bytes); return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } + void ddc_close(void *eeprom) { diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_custom.c new file mode 100644 index 000000000..4b8e300e5 --- /dev/null +++ b/src/video/vid_ddc_custom.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include + +#define EDID_BLOCK_SIZE 128 +#define EDID_HEADER 0x00FFFFFFFFFFFF00 +#define EDID_DECODE_HEADER "edid-decode (hex):" + +static size_t +read_block(FILE *fp, uint8_t *buf) +{ + uint8_t temp[64]; + size_t read = 0; + + for (int i = 0; i < 8; i++) { + if (!fgets(temp, sizeof(temp), fp)) { + return 0; + } + + char *tok = strtok(temp, " \t\r\n"); + + for (int j = 0; j < 16; j++) { + if (!tok) { + return 0; + } + + buf[read++] = strtoul(tok, NULL, 16); + tok = strtok(NULL, " \t\r\n"); + } + } + + return read; +} + +size_t +ddc_load_edid(char *path, uint8_t *buf, size_t size) +{ + FILE *fp = fopen(path, "rb"); + size_t offset = 0; + uint8_t temp[64]; + + if (!fp) { + return 0; + } + + // Check the beginning of the file for the EDID header. + uint64_t header; + fread(&header, sizeof(header), 1, fp); + + if (header == EDID_HEADER) { + // Binary format. Read as is + fseek(fp, 0, SEEK_SET); + offset = fread(buf, 1, size, fp); + + fclose(fp); + return offset; + } + + // Reopen in text mode. + fclose(fp); + fp = fopen(path, "rt"); + + if (!fp) { + return 0; + } + + // Skip the UTF-8 BOM, if any. + if (fread(temp, 1, 3, fp) != 3) { + fclose(fp); + return 0; + }; + + if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF) { + fseek(fp, -3, SEEK_CUR); + } + + // Find the `edid-decode (hex):` header + do { + if (!fgets(temp, sizeof(temp), fp)) { + fclose(fp); + return 0; + } + } while (strncmp(temp, EDID_DECODE_HEADER, sizeof(EDID_DECODE_HEADER) - 1)); + + while (offset + EDID_BLOCK_SIZE <= size) { + // Skip any whitespace before the next block + do { + if (!fgets(temp, sizeof(temp), fp)) { + fclose(fp); + return offset; + } + } while (strspn(temp, " \t\r\n") == strlen(temp)); + + fseek(fp, -strlen(temp), SEEK_CUR); + + // Read the block + size_t block = read_block(fp, buf + offset); + + if (block != EDID_BLOCK_SIZE) { + break; + } + + offset += block; + } + + fclose(fp); + return offset; +} From 33c0f2eba87231bcb04350204e297a1fcfd0cbbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Mon, 1 Sep 2025 18:42:29 +0200 Subject: [PATCH 002/138] Fix --- src/video/vid_ddc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index aeaba3965..ba6ac2a6d 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -278,7 +278,7 @@ ddc_init_with_custom_edid(char *edid_path, void *i2c) uint8_t *edid_bytes = malloc(size); memcpy(edid_bytes, buffer, size); - return i2c_eeprom_init(i2c, 0x50, edid_bytes, size); + return i2c_eeprom_init(i2c, 0x50, edid_bytes, size, 0); } void * @@ -293,7 +293,7 @@ ddc_init(void *i2c) } uint8_t *edid_bytes; - size_t edid_size = ddc_generate_default_edid(&edid_bytes); + size_t edid_size = ddc_create_default_edid(&edid_bytes); return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } From 948e18945ba74cce09243ebe8a2b77844b714012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 00:06:41 +0200 Subject: [PATCH 003/138] Fix seeking in text mode --- src/video/vid_ddc_custom.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_custom.c index 4b8e300e5..e17f7a037 100644 --- a/src/video/vid_ddc_custom.c +++ b/src/video/vid_ddc_custom.c @@ -40,6 +40,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) FILE *fp = fopen(path, "rb"); size_t offset = 0; uint8_t temp[64]; + long pos; if (!fp) { return 0; @@ -66,6 +67,12 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) return 0; } +#ifdef _WIN32 + // Disable buffering on Windows because of a UCRT bug. + // https://developercommunity.visualstudio.com/t/fseek-ftell-fail-in-text-mode-for-unix-style-text/425878 + setvbuf(fp, NULL, _IONBF, 0); +#endif + // Skip the UTF-8 BOM, if any. if (fread(temp, 1, 3, fp) != 3) { fclose(fp); @@ -73,10 +80,10 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) }; if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF) { - fseek(fp, -3, SEEK_CUR); + rewind(fp); } - // Find the `edid-decode (hex):` header + // Find the `edid-decode (hex):` header. do { if (!fgets(temp, sizeof(temp), fp)) { fclose(fp); @@ -85,17 +92,18 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) } while (strncmp(temp, EDID_DECODE_HEADER, sizeof(EDID_DECODE_HEADER) - 1)); while (offset + EDID_BLOCK_SIZE <= size) { - // Skip any whitespace before the next block + // Skip any whitespace before the next block. do { + pos = ftell(fp); if (!fgets(temp, sizeof(temp), fp)) { fclose(fp); return offset; } } while (strspn(temp, " \t\r\n") == strlen(temp)); - fseek(fp, -strlen(temp), SEEK_CUR); + fseek(fp, pos, SEEK_SET); - // Read the block + // Read the block. size_t block = read_block(fp, buf + offset); if (block != EDID_BLOCK_SIZE) { From 8ab80ca26f768606638fd6c1075e75e06ffb6275 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 00:18:36 +0200 Subject: [PATCH 004/138] Fix sign warnings --- src/video/vid_ddc_custom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_custom.c index e17f7a037..d042bdf61 100644 --- a/src/video/vid_ddc_custom.c +++ b/src/video/vid_ddc_custom.c @@ -11,7 +11,7 @@ static size_t read_block(FILE *fp, uint8_t *buf) { - uint8_t temp[64]; + char temp[64]; size_t read = 0; for (int i = 0; i < 8; i++) { @@ -39,7 +39,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) { FILE *fp = fopen(path, "rb"); size_t offset = 0; - uint8_t temp[64]; + char temp[64]; long pos; if (!fp) { From 37a1aaa72130bc4c78cc4463080a47799d2d5f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 00:30:05 +0200 Subject: [PATCH 005/138] Rename file, add copyright header --- src/video/CMakeLists.txt | 2 +- ...vid_ddc_custom.c => vid_ddc_edid_custom.c} | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) rename src/video/{vid_ddc_custom.c => vid_ddc_edid_custom.c} (82%) diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index 4667a3b4f..98a9cb385 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -44,7 +44,7 @@ add_library(vid OBJECT # DDC / monitor identification stuff vid_ddc.c - vid_ddc_custom.c + vid_ddc_edid_custom.c # CARDS start here diff --git a/src/video/vid_ddc_custom.c b/src/video/vid_ddc_edid_custom.c similarity index 82% rename from src/video/vid_ddc_custom.c rename to src/video/vid_ddc_edid_custom.c index d042bdf61..de037b85e 100644 --- a/src/video/vid_ddc_custom.c +++ b/src/video/vid_ddc_edid_custom.c @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Custom monitor EDID file loader. + * + * + * + * Authors: Cacodemon345, + * David Hrdlička, + * + * Copyright 2025 Cacodemon. + * Copyright 2025 David Hrdlička. + */ + #include #include #include From 54fc345ee5dc9bff0a11af556275113c8152fdae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Tue, 2 Sep 2025 10:28:58 +0200 Subject: [PATCH 006/138] Fix warning --- src/video/vid_ddc_edid_custom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ddc_edid_custom.c b/src/video/vid_ddc_edid_custom.c index de037b85e..2febde67e 100644 --- a/src/video/vid_ddc_edid_custom.c +++ b/src/video/vid_ddc_edid_custom.c @@ -98,7 +98,7 @@ ddc_load_edid(char *path, uint8_t *buf, size_t size) return 0; }; - if (temp[0] != 0xEF || temp[1] != 0xBB || temp[2] != 0xBF) { + if ((uint8_t) temp[0] != 0xEF || (uint8_t) temp[1] != 0xBB || (uint8_t) temp[2] != 0xBF) { rewind(fp); } From 766734eb3aef059bae95932c7f25699370544ddb Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:36:41 +0200 Subject: [PATCH 007/138] 386DX: Force external cache enabled to improve performance. --- src/cpu/cpu.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ec026d95e..f169f0f3f 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1080,6 +1080,9 @@ cpu_set(void) timing_jmp_rm = 12; timing_jmp_pm = 27; timing_jmp_pm_gate = 45; + + if (cpu_s->cpu_type == CPU_386DX) + cpu_cache_ext_enabled = 1; break; case CPU_486SLC: @@ -1161,6 +1164,9 @@ cpu_set(void) timing_jmp_pm_gate = 37; timing_misaligned = 3; + + if (cpu_s->cpu_type == CPU_386DX) + cpu_cache_ext_enabled = 1; break; case CPU_i486SX_SLENH: @@ -4473,13 +4479,6 @@ cpu_update_waitstates(void) if (cpu_cache_int_enabled) { /* Disable prefetch emulation */ cpu_prefetch_cycles = 0; - } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates + 1; - cpu_cycles_read = cpu_waitstates + 1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); - cpu_cycles_write = cpu_waitstates + 1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else if (cpu_cache_ext_enabled) { /* Use cache timings */ cpu_prefetch_cycles = cpu_s->cache_read_cycles; @@ -4487,6 +4486,13 @@ cpu_update_waitstates(void) cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; cpu_cycles_write = cpu_s->cache_write_cycles; cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; + } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { + /* Waitstates override */ + cpu_prefetch_cycles = cpu_waitstates + 1; + cpu_cycles_read = cpu_waitstates + 1; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); + cpu_cycles_write = cpu_waitstates + 1; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else { /* Use memory timings */ cpu_prefetch_cycles = cpu_s->mem_read_cycles; From b825aed242923d0c24730198bf2b843fd64b80fa Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:41:30 +0200 Subject: [PATCH 008/138] 386DX: Fix cache defaults to be the equivalent of 0 wait states. --- src/cpu/cpu_table.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index db8c89ebb..516de061c 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1367,8 +1367,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 3, .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 2 }, { @@ -1384,8 +1384,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1401,8 +1401,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1418,8 +1418,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1435,8 +1435,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -1461,8 +1461,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 3, .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 2 }, { @@ -1478,8 +1478,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1495,8 +1495,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { .name = "", 0 } @@ -1521,8 +1521,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1538,8 +1538,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1555,8 +1555,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -1581,8 +1581,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1598,8 +1598,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1615,8 +1615,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } From c5be7e9261a0bd9f5bc002941a13f2a7a4986177 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:45:01 +0200 Subject: [PATCH 009/138] More fixed and disabled the wait states selection on 386DX. --- src/cpu/cpu_table.c | 10 +++++----- src/qt/qt_settingsmachine.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 516de061c..3adbc7202 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -2096,7 +2096,7 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, + .cache_read_cycles = 2, .cache_write_cycles = 3, .atclk_div = 3 }, @@ -2113,8 +2113,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -2130,8 +2130,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 0063ac727..e52553196 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -281,7 +281,7 @@ SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) int cpuId = ui->comboBoxSpeed->currentData().toInt(); uint cpuType = cpuFamily->cpus[cpuId].cpu_type; - if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { + if ((cpuType >= CPU_286) && (cpuType < CPU_386DX)) { ui->comboBoxWaitStates->setEnabled(true); ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates); } else { From 5a2f9eacbf67829faa931731c1519d09895a4ea1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 16:46:12 +0200 Subject: [PATCH 010/138] And another fix. --- src/cpu/cpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index f169f0f3f..ff806297e 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1165,8 +1165,7 @@ cpu_set(void) timing_misaligned = 3; - if (cpu_s->cpu_type == CPU_386DX) - cpu_cache_ext_enabled = 1; + cpu_cache_ext_enabled = 1; break; case CPU_i486SX_SLENH: From d8b7b258202c9f23c92a90af60708485dd188de6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 22:47:13 +0200 Subject: [PATCH 011/138] Rename MGA DMA states to MGA_DMA_STATE in preparation for the 6.0 CPU rewrite. --- src/video/vid_mga.c | 70 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index eded49cf6..7fdc04e9e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -424,9 +424,9 @@ enum { }; enum { - DMA_STATE_IDLE = 0, - DMA_STATE_PRI, - DMA_STATE_SEC + MGA_DMA_STATE_IDLE = 0, + MGA_DMA_STATE_PRI, + MGA_DMA_STATE_SEC }; typedef struct { @@ -1600,7 +1600,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) case REG_STATUS + 2: ret = (mystique->status >> 16) & 0xff; if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY - || mystique->dma.state != DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) + || mystique->dma.state != MGA_DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) ret |= (STATUS_DWGENGSTS >> 16); break; case REG_STATUS + 3: @@ -2179,7 +2179,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_OPMODE: thread_wait_mutex(mystique->dma.lock); - mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ + mystique->dma.state = MGA_DMA_STATE_IDLE; /* Interrupt DMA. */ thread_release_mutex(mystique->dma.lock); mystique->dmamod = (val >> 2) & 3; mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); @@ -2200,10 +2200,10 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; - if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { mystique->dma.words_expected = 0; } - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; thread_release_mutex(mystique->dma.lock); break; @@ -2240,7 +2240,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); mystique->dma.pri_state = 0; mystique->dma.sec_state = 0; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; thread_release_mutex(mystique->dma.lock); break; @@ -2599,12 +2599,12 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_SECEND: mystique->dma.secend = val; - if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) - mystique->dma.state = DMA_STATE_SEC; + if (mystique->dma.state != MGA_DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) + mystique->dma.state = MGA_DMA_STATE_SEC; break; case REG_SOFTRAP: - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; @@ -2683,11 +2683,11 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) thread_wait_mutex(mystique->dma.lock); mystique->dma.primend = val; //pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend); - if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 0; mystique->status &= ~STATUS_ENDPRDMASTS; - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } @@ -2699,7 +2699,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) { mystique->dma.primaddress = mystique->dma.primend; mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; } thread_release_mutex(mystique->dma.lock); break; @@ -2935,7 +2935,7 @@ run_dma(mystique_t *mystique) return; } - if (mystique->dma.state == DMA_STATE_IDLE) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE) { if (!(mystique->status & STATUS_ENDPRDMASTS)) { /* Force this to appear. */ @@ -2945,14 +2945,14 @@ run_dma(mystique_t *mystique) return; } - while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { + while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != MGA_DMA_STATE_IDLE) { switch (atomic_load(&mystique->dma.state)) { - case DMA_STATE_PRI: + case MGA_DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; break; } if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { @@ -2965,7 +2965,7 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; break; } @@ -3000,31 +3000,31 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - if (mystique->dma.state == DMA_STATE_SEC) { + if (mystique->dma.state == MGA_DMA_STATE_SEC) { mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; } break; default: - fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + fatal("MGA_DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); } break; - case DMA_STATE_SEC: + case MGA_DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3039,11 +3039,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3073,11 +3073,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3090,11 +3090,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3110,11 +3110,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3123,7 +3123,7 @@ run_dma(mystique_t *mystique) break; default: - fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + fatal("MGA_DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); } break; @@ -3145,7 +3145,7 @@ fifo_thread(void *priv) thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); - while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { + while (!FIFO_EMPTY || mystique->dma.state != MGA_DMA_STATE_IDLE) { int words_transferred = 0; while (!FIFO_EMPTY && words_transferred < 100) { From 4063ce77398c78ee34ad3a0b80febc72f2042d5d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 2 Sep 2025 23:06:29 +0200 Subject: [PATCH 012/138] Fix two CLang warnings. --- src/qt/qt_vmmanager_main.cpp | 2 +- src/qt/qt_vmmanager_mainwindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index e53e2e407..cc3904e97 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -351,7 +351,7 @@ illegal_chars: } }); - connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [this] () { + connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [] () { vmm_main_window->updateSettings(); }); diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 55e980ec9..f698f1ccd 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -130,7 +130,7 @@ VMManagerMainWindow(QWidget *parent) connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated); #ifdef Q_OS_WINDOWS connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated); - connect(this, &VMManagerMainWindow::preferencesUpdated, [this] () { vmm_dark_mode_filter->reselectDarkMode(); }); + connect(this, &VMManagerMainWindow::preferencesUpdated, [] () { vmm_dark_mode_filter->reselectDarkMode(); }); #endif { From 649f81361426a937f6418b998c77198511da9660 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Sep 2025 00:20:20 +0200 Subject: [PATCH 013/138] AT KBC: Make sure AMI KBC revisions do not support commands they are not supposed to support. --- src/device/kbc_at.c | 75 +++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 4c0ea4155..186804e22 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -975,7 +975,7 @@ write_cmd_data_ami(void *priv, uint8_t val) return 0; case 0xc1: - kbc_at_log("ATkbc: AMI MegaKey - write %02X to P1\n", val); + kbc_at_log("ATkbc: AMI - write %02X to P1\n", val); dev->p1 = val; return 0; @@ -1160,11 +1160,14 @@ write_cmd_ami(void *priv, uint8_t val) case 0xaf: /* set extended controller RAM */ if ((kbc_ven != KBC_VEN_SIEMENS) && (kbc_ven != KBC_VEN_ALI)) { - kbc_at_log("ATkbc: set extended controller RAM\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - dev->command_phase = 1; - ret = 0; + if (((kbc_ami_revision >= 'H') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + kbc_at_log("ATkbc: set extended controller RAM\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + dev->command_phase = 1; + ret = 0; + } } break; @@ -1214,27 +1217,33 @@ write_cmd_ami(void *priv, uint8_t val) break; case 0xc1: /* write P1 */ - kbc_at_log("ATkbc: AMI MegaKey - write P1\n"); + kbc_at_log("ATkbc: AMI - write P1\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; ret = 0; break; case 0xc4: - /* set KBC line P14 low */ - kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) low\n"); - dev->p1 &= 0xef; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P14 low */ + kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) low\n"); + dev->p1 &= 0xef; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xc5: - /* set KBC line P15 low */ - kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); - dev->p1 &= 0xdf; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P15 low */ + kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); + dev->p1 &= 0xdf; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xc8: @@ -1271,20 +1280,26 @@ write_cmd_ami(void *priv, uint8_t val) break; case 0xcc: - /* set KBC line P14 high */ - kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) high\n"); - dev->p1 |= 0x10; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P14 high */ + kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) high\n"); + dev->p1 |= 0x10; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xcd: /* set KBC line P15 high */ - kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); - dev->p1 |= 0x20; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); + dev->p1 |= 0x20; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xef: /* ??? - sent by AMI486 */ From 5f065614694e6e2450a67e25ee110094d47f2c73 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:49:27 +0200 Subject: [PATCH 014/138] EEPROM use changes and misc (September 3rd, 2025) 1.Move the 93cxx EEPROM implementation to the mem directory since it's used by cards which are not nics (e.g.: DC390 SCSI and S3 ELSA cards). 2. DC390 specific: remove the implementation used there and use the generic one from mem (used to be on the network directory) as well as fixing bus reset when interrupts are related. 3. S3: when the 64k size is selected in the LFB, use the SVGA 64k mapping as LFB (0xA0000). --- src/mem/CMakeLists.txt | 1 + .../net_eeprom_nmc93cxx.c => mem/nmc93cxx.c} | 9 +- src/network/CMakeLists.txt | 4 - src/network/net_rtl8139.c | 2 +- src/network/net_tulip.c | 2 +- src/scsi/scsi_pcscsi.c | 276 +++++------------- src/video/vid_s3.c | 9 +- 7 files changed, 90 insertions(+), 213 deletions(-) rename src/{network/net_eeprom_nmc93cxx.c => mem/nmc93cxx.c} (97%) diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 0e52beb4e..3984c2d02 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(mem OBJECT intel_flash.c mem.c mmu_2386.c + nmc93cxx.c rom.c row.c smram.c diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/mem/nmc93cxx.c similarity index 97% rename from src/network/net_eeprom_nmc93cxx.c rename to src/mem/nmc93cxx.c index 05fd43ed0..50905bae2 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -28,7 +28,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/nvr.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_unused.h> #ifdef ENABLE_NMC93CXX_EEPROM_LOG @@ -256,7 +256,12 @@ static void nmc93cxx_eeprom_close(void *priv) { nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv; - free(eeprom); + FILE *fp = nvr_fopen(eeprom->filename, "wb"); + if (fp) { + fwrite(eeprom->dev.data, 2, eeprom->size, fp); + fclose(fp); + } + free(priv); } uint16_t * diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 3f7ba427c..782672e98 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -28,7 +28,6 @@ list(APPEND net_sources net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c @@ -71,9 +70,6 @@ if(NETSWITCH) endif() if (UNIX) - if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") - set_source_files_properties(net_slirp.c PROPERTIES COMPILE_FLAGS "-I/usr/local/include") - endif() find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) find_library(VDE_LIB vdeplug) diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index f1e531deb..41ce86f6b 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include "cpu.h" #include <86box/plat_unused.h> diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 883ba53ad..cbf3b704e 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -31,7 +31,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> #include <86box/bswap.h> diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index f91eef683..04c188705 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -40,11 +40,11 @@ #include <86box/pci.h> #include <86box/device.h> #include <86box/nvr.h> +#include <86box/nmc93cxx.h> #include <86box/plat.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_pcscsi.h> -#include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> #include "cpu.h" @@ -179,7 +179,6 @@ typedef struct esp_t { int BIOSBase; int MMIOBase; rom_t bios; - ati_eeprom_t eeprom; int PCIBase; uint8_t rregs[ESP_REGS]; @@ -223,9 +222,14 @@ typedef struct esp_t { uint8_t irq_state; uint8_t pos_regs[8]; + + uint8_t eeprom_inst; + uint8_t eeprom_data[128]; + + nmc93cxx_eeprom_t *eeprom; } esp_t; -static esp_t reset_state = { 0 }; +static esp_t *reset_state = NULL; #define READ_FROM_DEVICE 1 #define WRITE_TO_DEVICE 0 @@ -1534,19 +1538,19 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_BUSRESET: esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); - if (dev->mca) { - esp_lower_irq(dev); - esp_hard_reset(dev); - } else - esp_pci_soft_reset(dev); - - for (uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - } + if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); + } else { + if (dev->mca) { + esp_lower_irq(dev); + esp_hard_reset(dev); + } else + esp_pci_soft_reset(dev); } break; case CMD_TI: @@ -1994,180 +1998,6 @@ esp_bios_disable(esp_t *dev) #define EE_ADAPT_OPTION_INT13 0x04 #define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 -/*To do: make this separate from the SCSI card*/ -static void -dc390_save_eeprom(esp_t *dev) -{ - FILE *fp = nvr_fopen(dev->nvr_path, "wb"); - if (!fp) - return; - fwrite(dev->eeprom.data, 1, 128, fp); - fclose(fp); -} - -static void -dc390_write_eeprom(esp_t *dev, int ena, int clk, int dat) -{ - /*Actual EEPROM is the same as the one used by the ATI cards, the 93cxx series.*/ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t tick = eeprom->count; - uint8_t eedo = eeprom->out; - uint16_t address = eeprom->address; - uint8_t command = eeprom->opcode; - - esp_log("EEPROM CS=%02x,SK=%02x,DI=%02x,DO=%02x,tick=%d\n", - ena, clk, dat, eedo, tick); - - if (!eeprom->oldena && ena) { - esp_log("EEPROM Start chip select cycle\n"); - tick = 0; - command = 0; - address = 0; - } else if (eeprom->oldena && !ena) { - if (!eeprom->wp) { - uint8_t subcommand = address >> 4; - if (command == 0 && subcommand == 2) { - esp_log("EEPROM Erase All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (command == 3) { - esp_log("EEPROM Erase Word\n"); - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (tick >= 26) { - if (command == 1) { - esp_log("EEPROM Write Word\n"); - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } else if (command == 0 && subcommand == 1) { - esp_log("EEPROM Write All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } - } - } - eedo = 1; - esp_log("EEPROM DO read\n"); - } else if (ena && !eeprom->oldclk && clk) { - if (tick == 0) { - if (dat == 0) { - esp_log("EEPROM Got correct 1st start bit, waiting for 2nd start bit (1)\n"); - tick++; - } else { - esp_log("EEPROM Wrong 1st start bit (is 1, should be 0)\n"); - tick = 2; - } - } else if (tick == 1) { - if (dat != 0) { - esp_log("EEPROM Got correct 2nd start bit, getting command + address\n"); - tick++; - } else { - esp_log("EEPROM 1st start bit is longer than needed\n"); - } - } else if (tick < 4) { - tick++; - command <<= 1; - if (dat) - command += 1; - } else if (tick < 10) { - tick++; - address = (address << 1) | dat; - if (tick == 10) { - esp_log("EEPROM command = %02x, address = %02x (val = %04x)\n", command, - address, eeprom->data[address]); - if (command == 2) - eedo = 0; - address = address % 64; - if (command == 0) { - switch (address >> 4) { - case 0: - esp_log("EEPROM Write disable command\n"); - eeprom->wp = 1; - break; - case 1: - esp_log("EEPROM Write all command\n"); - break; - case 2: - esp_log("EEPROM Erase all command\n"); - break; - case 3: - esp_log("EEPROM Write enable command\n"); - eeprom->wp = 0; - break; - - default: - break; - } - } else { - esp_log("EEPROM Read, write or erase word\n"); - eeprom->dat = eeprom->data[address]; - } - } - } else if (tick < 26) { - tick++; - if (command == 2) { - esp_log("EEPROM Read Word\n"); - eedo = ((eeprom->dat & 0x8000) != 0); - } - eeprom->dat <<= 1; - eeprom->dat += dat; - } else { - esp_log("EEPROM Additional unneeded tick, not processed\n"); - } - } - - eeprom->count = tick; - eeprom->oldena = ena; - eeprom->oldclk = clk; - eeprom->out = eedo; - eeprom->address = address; - eeprom->opcode = command; - esp_log("EEPROM EEDO = %d\n", eeprom->out); -} - -static void -dc390_load_eeprom(esp_t *dev) -{ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t *nvr = (uint8_t *) eeprom->data; - int i; - uint16_t checksum = 0; - FILE *fp; - - eeprom->out = 1; - - fp = nvr_fopen(dev->nvr_path, "rb"); - if (fp) { - esp_log("EEPROM Load\n"); - if (fread(nvr, 1, 128, fp) != 128) - fatal("dc390_eeprom_load(): Error reading data\n"); - fclose(fp); - } else { - for (i = 0; i < 16; i++) { - nvr[i * 2] = 0x57; - nvr[i * 2 + 1] = 0x00; - } - - esp_log("EEPROM Defaults\n"); - - nvr[EE_ADAPT_SCSI_ID] = 7; - nvr[EE_MODE2] = 0x0f; - nvr[EE_TAG_CMD_NUM] = 0x04; - nvr[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; - for (i = 0; i < EE_CHKSUM1; i += 2) { - checksum += ((nvr[i] & 0xff) | (nvr[i + 1] << 8)); - esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, nvr[i]); - } - - checksum = 0x1234 - checksum; - nvr[EE_CHKSUM1] = checksum & 0xff; - nvr[EE_CHKSUM2] = checksum >> 8; - esp_log("EEPROM Checksum = %04x\n", checksum); - } -} - static uint8_t esp_pci_read(UNUSED(int func), int addr, void *priv) { @@ -2181,10 +2011,10 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) if (!dev->has_bios || dev->local) return 0x22; else { - if (dev->eeprom.out) + if (nmc93cxx_eeprom_read(dev->eeprom)) return 0x22; else { - dev->eeprom.out = 1; + dev->eeprom->dev.out = 1; return 2; } } @@ -2270,9 +2100,9 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x80) { eesk = val & 0x80 ? 1 : 0; eedi = val & 0x40 ? 1 : 0; - dc390_write_eeprom(dev, 1, eesk, eedi); + nmc93cxx_eeprom_write(dev->eeprom, 1, eesk, eedi); } else if (addr == 0xc0) - dc390_write_eeprom(dev, 0, 0, 0); + nmc93cxx_eeprom_write(dev->eeprom, 0, 0, 0); // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); return; } @@ -2371,26 +2201,35 @@ esp_pci_reset(void *priv) { esp_t *dev = (esp_t *) priv; - timer_disable(&dev->timer); + if (reset_state != NULL) { + esp_io_remove(dev, dev->PCIBase, 0x80); + esp_bios_disable(dev); + timer_stop(&dev->timer); - reset_state.bios.mapping = dev->bios.mapping; + reset_state->bios.mapping = dev->bios.mapping; + reset_state->timer = dev->timer; + reset_state->pci_slot = dev->pci_slot; - reset_state.timer = dev->timer; + *dev = *reset_state; - reset_state.pci_slot = dev->pci_slot; - - memcpy(dev, &reset_state, sizeof(esp_t)); - - esp_pci_soft_reset(dev); + esp_pci_soft_reset(dev); + esp_log("PCI Reset.\n"); + } } static void * dc390_init(const device_t *info) { esp_t *dev = calloc(1, sizeof(esp_t)); + reset_state = calloc(1, sizeof(esp_t)); const char *bios_rev = NULL; uint32_t mask = 0; uint32_t size = 0x8000; + nmc93cxx_eeprom_params_t params; + char eeprom_filename[1024] = { 0 }; + char filename[1024] = { 0 }; + uint16_t checksum = 0x0000; + uint8_t i; dev->bus = scsi_get_bus(); @@ -2434,10 +2273,40 @@ dc390_init(const device_t *info) esp_bios_disable(dev); if (!dev->local) { - sprintf(dev->nvr_path, "dc390_%i.nvr", device_get_instance()); + dev->eeprom_inst = device_get_instance(); + + snprintf(eeprom_filename, sizeof(eeprom_filename), "dc390_%d.nvr", dev->eeprom_inst); /* Load the serial EEPROM. */ - dc390_load_eeprom(dev); + for (i = 0; i < 16; i++) { + dev->eeprom_data[i * 2] = 0x57; + dev->eeprom_data[i * 2 + 1] = 0x00; + } + + esp_log("EEPROM Defaults\n"); + + dev->eeprom_data[EE_ADAPT_SCSI_ID] = 7; + dev->eeprom_data[EE_MODE2] = 0x0f; + dev->eeprom_data[EE_TAG_CMD_NUM] = 0x04; + dev->eeprom_data[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; + for (i = 0; i < EE_CHKSUM1; i += 2) { + checksum += ((dev->eeprom_data[i] & 0xff) | (dev->eeprom_data[i + 1] << 8)); + esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, dev->eeprom_data[i]); + } + + checksum = 0x1234 - checksum; + dev->eeprom_data[EE_CHKSUM1] = checksum & 0xff; + dev->eeprom_data[EE_CHKSUM2] = checksum >> 8; + + params.nwords = 64; + params.default_content = (uint16_t *) dev->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, dev->eeprom_inst); + dev->eeprom = device_add_inst_params(&nmc93cxx_device, dev->eeprom_inst, ¶ms); + if (dev->eeprom == NULL) { + free(dev); + return NULL; + } } esp_pci_hard_reset(dev); @@ -2449,7 +2318,7 @@ dc390_init(const device_t *info) scsi_bus_set_speed(dev->bus, 10000000.0); - memcpy(&reset_state, dev, sizeof(esp_t)); + *reset_state = *dev; return dev; } @@ -2622,7 +2491,7 @@ ncr53c9x_mca_init(const device_t *info) fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4f; /* MCA board ID */ + dev->pos_regs[0] = 0x4d; /* MCA board ID */ dev->pos_regs[1] = 0x7f; mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); @@ -2646,6 +2515,11 @@ esp_close(void *priv) fifo8_destroy(&dev->fifo); fifo8_destroy(&dev->cmdfifo); + if (reset_state != NULL) { + free(reset_state); + reset_state = NULL; + } + free(dev); dev = NULL; } diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 943441f1c..fbf329e84 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -33,7 +33,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/rom.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include <86box/plat.h> #include <86box/thread.h> @@ -4807,10 +4807,10 @@ s3_updatemapping(s3_t *s3) break; } s3->linear_base &= ~(s3->linear_size - 1); - if (s3->linear_base == 0xa0000) { + if ((s3->linear_base == 0xa0000) || (s3->linear_size == 0x10000)) { mem_mapping_disable(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } } else { @@ -5071,6 +5071,7 @@ s3_accel_in(uint16_t port, void *priv) if (FIFO_FULL) temp = 0xff; } + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x8119: case 0x9949: @@ -5127,7 +5128,7 @@ s3_accel_in(uint16_t port, void *priv) s3->data_available = 0; } } - s3_log("FIFO Status Temp=%02x.\n", temp); + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x9d48: From 7e490d53403c03f8ef0e2adaa474783bbb1a2b5c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:50:01 +0200 Subject: [PATCH 015/138] Forgot the header. --- src/include/86box/{net_eeprom_nmc93cxx.h => nmc93cxx.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/include/86box/{net_eeprom_nmc93cxx.h => nmc93cxx.h} (100%) diff --git a/src/include/86box/net_eeprom_nmc93cxx.h b/src/include/86box/nmc93cxx.h similarity index 100% rename from src/include/86box/net_eeprom_nmc93cxx.h rename to src/include/86box/nmc93cxx.h From 5618dba9d1a75c8f652111a63358c7427f42a2c0 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 3 Sep 2025 00:53:26 +0200 Subject: [PATCH 016/138] Restore FreeBSD stuff that was removed accidentally --- src/network/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 782672e98..0943a9258 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -70,6 +70,9 @@ if(NETSWITCH) endif() if (UNIX) + if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set_source_files_properties(net_slirp.c PROPERTIES COMPILE_FLAGS "-I/usr/local/include") + endif() find_path(HAS_VDE "libvdeplug.h" PATHS ${VDE_INCLUDE_DIR} "/usr/include /usr/local/include" "/opt/homebrew/include" ) if(HAS_VDE) find_library(VDE_LIB vdeplug) From 15231c19aa887c44a2bbd7c5a89e2ab166377c98 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 3 Sep 2025 00:56:12 +0200 Subject: [PATCH 017/138] Config: Save and restore the full screen state if window size and position is set to be remembered. --- src/config.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/config.c b/src/config.c index 9fce92ded..adb5069cf 100644 --- a/src/config.c +++ b/src/config.c @@ -211,6 +211,8 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); + start_in_fullscreen = ini_section_get_int(cat, "start_in_fullscreen", 0); + window_remember = ini_section_get_int(cat, "window_remember", 0); if (!window_remember && !(vid_resize & 2)) @@ -2410,6 +2412,11 @@ save_general(void) else ini_section_delete_var(cat, "window_remember"); + if (video_fullscreen) + ini_section_set_int(cat, "start_in_fullscreen", video_fullscreen); + else + ini_section_delete_var(cat, "start_in_fullscreen"); + if (vid_resize & 2) { sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y); ini_section_set_string(cat, "window_fixed_res", temp); From f4f39f28588d84d3589d7852b85b4d765bb19ccd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Sep 2025 17:21:19 -0300 Subject: [PATCH 018/138] SLiRP: Force resetting of the range number --- src/include/86box/network.h | 1 + src/network/net_slirp.c | 5 ++--- src/network/network.c | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 01454c6f9..5a6651b5b 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -105,6 +105,7 @@ typedef struct netcard_conf_t { extern netcard_conf_t net_cards_conf[NET_CARD_MAX]; extern uint16_t net_card_current; +extern int slirp_card_num; typedef int (*NETRXCB)(void *, uint8_t *, int); typedef int (*NETSETLINKSTATE)(void *, uint32_t link_state); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index e8cfd6cd7..9d8231034 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -470,13 +470,13 @@ net_slirp_thread(void *priv) } #endif -static int slirp_card_num = 2; +int slirp_card_num = 2; /* Initialize SLiRP for use. */ void * net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), char *netdrv_errbuf) { - slirp_log("SLiRP: initializing...\n"); + pclog("SLiRP: initializing with range %d...\n", slirp_card_num); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr)); slirp->card = (netcard_t *) card; @@ -639,7 +639,6 @@ net_slirp_close(void *priv) } free(slirp->pkt.data); free(slirp); - slirp_card_num--; } const netdrv_t net_slirp_drv = { diff --git a/src/network/network.c b/src/network/network.c index 9b56515e8..661da7250 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -608,6 +608,7 @@ network_reset(void) ui_sb_update_icon(SB_NETWORK, 0); ui_sb_update_icon_write(SB_NETWORK, 0); + slirp_card_num = 2; #ifdef ENABLE_NETWORK_LOG network_dump_mutex = thread_create_mutex(); #endif From d4f53316077abe14dd494e5bb6a86b2e9193084b Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Sep 2025 17:38:49 -0300 Subject: [PATCH 019/138] Fix full screen command line parameter --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index adb5069cf..d3bc0c2de 100644 --- a/src/config.c +++ b/src/config.c @@ -211,7 +211,7 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); - start_in_fullscreen = ini_section_get_int(cat, "start_in_fullscreen", 0); + start_in_fullscreen |= ini_section_get_int(cat, "start_in_fullscreen", 0); window_remember = ini_section_get_int(cat, "window_remember", 0); From bb95ffaf5f130f5beec88d4116beb46cb31d8f3f Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 5 Sep 2025 20:41:49 -0300 Subject: [PATCH 020/138] SLiRP: Remove extraneous log [skip ci] --- src/network/net_slirp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 9d8231034..9bf1f63d4 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -476,7 +476,7 @@ int slirp_card_num = 2; void * net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), char *netdrv_errbuf) { - pclog("SLiRP: initializing with range %d...\n", slirp_card_num); + slirp_log("SLiRP: initializing with range %d...\n", slirp_card_num); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr)); slirp->card = (netcard_t *) card; From 65c7dfb2eed2cab535de32a19220870d7f6d2f79 Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 6 Sep 2025 02:53:30 -0500 Subject: [PATCH 021/138] Fix dynamic SCSI buffer window sizing causing SEGV --- src/include/86box/scsi_disk.h | 1 + src/scsi/scsi_disk.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index 293cc35e6..2d2371172 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -29,6 +29,7 @@ typedef struct scsi_disk_t { void * log; uint8_t * temp_buffer; + size_t temp_buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 8c09a30a1..bfa8b42cf 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -623,8 +623,15 @@ static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->temp_buffer == NULL) + if (dev->temp_buffer == NULL) { dev->temp_buffer = (uint8_t *) malloc(len); + dev->temp_buffer_sz = len; + } + if (len > dev->temp_buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->temp_buffer, len); + dev->temp_buffer = buf; + dev->temp_buffer_sz = len; + } } static void From 5225b37448d306ed9f0256e877512e32980e59ba Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 6 Sep 2025 16:34:10 -0500 Subject: [PATCH 022/138] Initial implementation of the Yamaha YMF-701 audio controller --- src/include/86box/snd_ad1848.h | 4 + src/include/86box/sound.h | 3 + src/sound/CMakeLists.txt | 1 + src/sound/snd_ad1848.c | 37 +++ src/sound/snd_ymf701.c | 526 +++++++++++++++++++++++++++++++++ src/sound/sound.c | 1 + 6 files changed, 572 insertions(+) create mode 100644 src/sound/snd_ymf701.c diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index a7e38a6f8..3105d75f9 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -69,6 +69,9 @@ typedef struct ad1848_t { pc_timer_t timer_count; uint64_t timer_latch; + pc_timer_t cs4231a_irq_timer; + uint8_t is_opl3sa; + int16_t buffer[SOUNDBUFLEN * 2]; int pos; @@ -88,6 +91,7 @@ extern void ad1848_update(ad1848_t *ad1848); extern void ad1848_speed_changed(ad1848_t *ad1848); extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r); +extern void ad1848_is_opl3sa(ad1848_t *ad1848); extern void ad1848_init(ad1848_t *ad1848, uint8_t type); diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 5f91ec9d0..9b7b19d4d 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -236,6 +236,9 @@ extern const device_t tndy_device; extern const device_t wss_device; extern const device_t ncr_business_audio_device; +/* Yamaha YMF-7xx */ +extern const device_t ymf701_device; + #ifdef USE_LIBSERIALPORT /* External Audio device OPL2Board (Host Connected hardware)*/ extern const device_t opl2board_device; diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt index 9e2a75198..fdc60b971 100644 --- a/src/sound/CMakeLists.txt +++ b/src/sound/CMakeLists.txt @@ -51,6 +51,7 @@ add_library(snd OBJECT snd_ym7128.c snd_optimc.c snd_opl_esfm.c + snd_ymf701.c ) # TODO: Should platform-specific audio driver be here? diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index e9a4390c0..bad9f4d22 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -76,6 +76,12 @@ ad1848_setdma(ad1848_t *ad1848, int newdma) ad1848->dma = newdma; } +void +ad1848_is_opl3sa(ad1848_t *ad1848) +{ + ad1848->is_opl3sa = 1; +} + void ad1848_updatevolmask(ad1848_t *ad1848) { @@ -285,6 +291,7 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) ad1848_t *ad1848 = (ad1848_t *) priv; uint8_t temp = 0; uint8_t updatefreq = 0; + double i8_timebase = 0; switch (addr & 3) { case 0: /* Index */ @@ -344,6 +351,21 @@ ad1848_write(uint16_t addr, uint8_t val, void *priv) ad1848->count = ad1848->regs[15] | (val << 8); break; + case 16: + if ((ad1848->type >= AD1848_TYPE_CS4231) && (ad1848->type < AD1848_TYPE_CS4235)) { + if (val & 0x40) { + ad1848_log("Timer Enable\n"); + ad1848_log("Timer value: %04X\n", ((ad1848->regs[21] << 8) + (ad1848->regs[20]))); + i8_timebase = (ad1848->regs[8] & 1) ? 9.92 : 9.969; + timer_set_delay_u64(&ad1848->cs4231a_irq_timer, (((ad1848->regs[21] << 8) + (ad1848->regs[20])) * i8_timebase * TIMER_USEC)); + } + else { + ad1848_log("Timer Disable\n"); + timer_disable(&ad1848->cs4231a_irq_timer); + } + } + break; + case 18 ... 19: if (ad1848->type >= AD1848_TYPE_CS4236B) { if (ad1848->type >= AD1848_TYPE_CS4235) { @@ -502,6 +524,8 @@ readonly_x: ad1848_updatefreq(ad1848); temp = (ad1848->type < AD1848_TYPE_CS4231) ? 2 : ((ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4); + if (ad1848->is_opl3sa) + temp = 2; /* OPL3-SA CODEC is CS4231-based but uses Aux1 for CD audio */ if (ad1848->regs[temp] & 0x80) ad1848->cd_vol_l = 0; else @@ -746,6 +770,16 @@ ad1848_poll(void *priv) } } +void +cs4231a_irq_poll(void *priv) +{ + ad1848_t *ad1848 = (ad1848_t *) priv; + ad1848_log("Firing timer IRQ\n"); + picint(1 << ad1848->irq); + ad1848_log("Setting timer interrupt bit in I24\n"); + ad1848->regs[24] |= 0x40; +} + void ad1848_filter_cd_audio(int channel, double *buffer, void *priv) { @@ -892,4 +926,7 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) if ((ad1848->type != AD1848_TYPE_DEFAULT) && (ad1848->type != AD1848_TYPE_CS4248)) sound_set_cd_audio_filter(ad1848_filter_cd_audio, ad1848); + + if ((ad1848->type >= AD1848_TYPE_CS4231) && (ad1848->type < AD1848_TYPE_CS4235)) + timer_add(&ad1848->cs4231a_irq_timer, cs4231a_irq_poll, ad1848, 0); } diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c new file mode 100644 index 000000000..430bfec4c --- /dev/null +++ b/src/sound/snd_ymf701.c @@ -0,0 +1,526 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running 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. + * + * Yamaha YMF-701 (OPL3-SA) audio controller emulation. + * + * + * + * Authors: Cacodemon345 + * Eluan Costa Miranda + * win2kgamer + * + * Copyright 2022 Cacodemon345. + * Copyright 2020 Eluan Costa Miranda. + * Copyright 2025 win2kgamer + */ + +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/midi.h> +#include <86box/timer.h> +#include <86box/pic.h> +#include <86box/sound.h> +#include <86box/gameport.h> +#include <86box/snd_ad1848.h> +#include <86box/snd_sb.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/plat_unused.h> +#include <86box/log.h> + +#ifdef ENABLE_YMF701_LOG +int ymf701_do_log = ENABLE_YMF701_LOG; + +static void +ymf701_log(void *priv, const char *fmt, ...) +{ + if (ymf701_do_log) { + va_list ap; + va_start(ap, fmt); + log_out(priv, fmt, ap); + va_end(ap); + } +} +#else +# define ymf701_log(fmt, ...) +#endif + +static int ymf701_wss_dma[4] = { 0, 0, 1, 3 }; +static int ymf701_wss_irq[8] = { 0, 7, 9, 10, 11, 0, 0, 0 }; + +typedef struct ymf701_t { + uint8_t type; + uint8_t fm_type; + + uint8_t wss_config; + uint8_t reg_enabled; + + uint16_t cur_addr; + uint16_t cur_wss_addr; + uint16_t cur_mpu401_addr; + + int cur_irq; + int cur_dma; + int cur_wss_enabled; + int cur_wss_irq; + int cur_wss_dma; + int cur_mpu401_irq; + int cur_mpu401_enabled; + void *gameport; + + uint8_t cur_mode; + + ad1848_t ad1848; + mpu_t *mpu; + + sb_t *sb; + uint8_t index; + uint8_t regs[6]; + uint8_t passwd_phase; + + uint8_t oldreadback; + + void * log; /* New logging system */ +} ymf701_t; + +static void +ymf701_filter_opl(void *priv, double *out_l, double *out_r) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + + if (ymf701->cur_wss_enabled) { + ad1848_filter_aux2((void *) &ymf701->ad1848, out_l, out_r); + } +} + +static uint8_t +ymf701_wss_read(uint16_t addr, void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + uint8_t ret = 0x00; + uint8_t port = addr - ymf701->cur_wss_addr; + + ymf701_log(ymf701->log, "WSS Read port = %04X\n", port); + + switch (port) { + case 0: + ret = ymf701->wss_config; + break; + case 3: + ret = 0x04 | (ymf701->wss_config & 0x40); + break; + default: + ret = ymf701->wss_config; + break; + } + ymf701_log(ymf701->log, "WSS Read: addr = %02X, val = %02X\n", addr, ret); + return ret; +} + +static void +ymf701_wss_write(uint16_t addr, uint8_t val, void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + uint8_t port = addr - ymf701->cur_wss_addr; + + ymf701_log(ymf701->log, "WSS Write: addr = %02X, val = %02X\n", addr, val); + switch (port) { + case 0: + ymf701->wss_config = val; + ymf701->cur_wss_dma = ymf701_wss_dma[val & 3]; + ymf701->cur_wss_irq = ymf701_wss_irq[(val >> 3) & 7]; + ad1848_setdma(&ymf701->ad1848, ymf701_wss_dma[val & 3]); + ad1848_setirq(&ymf701->ad1848, ymf701_wss_irq[(val >> 3) & 7]); + ymf701_log(ymf701->log, "Set IRQ to %02X\n", ymf701->cur_wss_irq); + ymf701_log(ymf701->log, "Set DMA to %02X\n", ymf701->cur_wss_dma); + break; + default: + break; + } +} + +static void +ymf701_get_buffer(int32_t *buffer, int len, void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + + /* wss part */ + ad1848_update(&ymf701->ad1848); + for (int c = 0; c < len * 2; c++) + buffer[c] += (ymf701->ad1848.buffer[c] / 2); + + ymf701->ad1848.pos = 0; + + /* sbprov2 part */ + sb_get_buffer_sbpro(buffer, len, ymf701->sb); +} + +static void +ymf701_remove_opl(ymf701_t *ymf701) +{ + io_removehandler(ymf701->cur_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_removehandler(ymf701->cur_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_removehandler(0x0388, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); +} + +static void +ymf701_add_opl(ymf701_t *ymf701) +{ + /* DSP I/O handler is activated in sb_dsp_setaddr */ + io_sethandler(ymf701->cur_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(ymf701->cur_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(0x0388, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); +} + +static void +ymf701_reg_write(uint16_t addr, uint8_t val, void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + uint16_t idx; + uint8_t old = ymf701->regs[idx]; + static uint8_t reg_enable_phase = 0; + + if (ymf701->reg_enabled) { + ymf701_log(ymf701->log, "Write with reg access enabled:\n"); + ymf701_log(ymf701->log, "addr = %02X, val = %02X\n", addr, val); + switch (addr) { + case 0xF86: + ymf701->index = val; + ymf701->passwd_phase = 0x01; + ymf701_log(ymf701->log, "Passwd phase 1\n"); + break; + case 0xF87: + switch (ymf701->index) { + case 0x01: /* WSS Config */ + ymf701->regs[0x01] = val; + ymf701->cur_mode = ymf701->cur_wss_enabled = !!(val & 0x20); + + sound_set_cd_audio_filter(NULL, NULL); + if (ymf701->cur_wss_enabled) /* WSS */ + sound_set_cd_audio_filter(ad1848_filter_cd_audio, &ymf701->ad1848); + else /* SBPro */ + sound_set_cd_audio_filter(sbpro_filter_cd_audio, ymf701->sb); + + io_removehandler(ymf701->cur_wss_addr, 0x0004, ymf701_wss_read, NULL, NULL, ymf701_wss_write, NULL, NULL, ymf701); + io_removehandler(ymf701->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &ymf701->ad1848); + switch ((val >> 3) & 0x3) { + case 0: /* WSBase = 0x530 */ + ymf701_log(ymf701->log, "WSS base is now 530h\n"); + ymf701->cur_wss_addr = 0x530; + break; + case 1: /* WSBase = 0xE80 */ + ymf701_log(ymf701->log, "WSS base is now E80h\n"); + ymf701->cur_wss_addr = 0xE80; + break; + case 2: /* WSBase = 0xF40 */ + ymf701_log(ymf701->log, "WSS base is now F40h\n"); + ymf701->cur_wss_addr = 0xF40; + break; + case 3: /* WSBase = 0x604 */ + ymf701_log(ymf701->log, "WSS base is now 604h\n"); + ymf701->cur_wss_addr = 0x604; + break; + default: + break; + } + io_sethandler(ymf701->cur_wss_addr, 0x0004, ymf701_wss_read, NULL, NULL, ymf701_wss_write, NULL, NULL, ymf701); + io_sethandler(ymf701->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &ymf701->ad1848); + break; + case 0x02: /* SB Config */ + ymf701->regs[0x02] = val; + io_removehandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + ymf701_remove_opl(ymf701); + ymf701->cur_addr = (val & 0x20) ? 0x240 : 0x220; + switch (val & 0x3) { + case 0: + ymf701->cur_dma = -1; + break; + case 1: + ymf701->cur_dma = 0; + break; + case 2: + ymf701->cur_dma = 1; + break; + case 3: + ymf701->cur_dma = 3; + break; + } + switch ((val >> 2) & 0x7) { + case 0: + ymf701->cur_irq = -1; + break; + case 1: + ymf701->cur_irq = 5; + break; + case 2: + ymf701->cur_irq = 7; + break; + case 3: + ymf701->cur_irq = 9; + break; + case 4: + ymf701->cur_irq = 10; + break; + case 5: + ymf701->cur_irq = 11; + break; + default: + break; + } + sb_dsp_setaddr(&ymf701->sb->dsp, ymf701->cur_addr); + sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_irq); + sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_dma); + ymf701_add_opl(ymf701); + io_sethandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + break; + case 0x03: /* MPU/OPL/Gameport Config */ + ymf701->regs[0x03] = val; + switch ((val >> 2) & 0x7) { + case 0: + ymf701->cur_mpu401_irq = -1; + break; + case 1: + ymf701->cur_mpu401_irq = 5; + break; + case 2: + ymf701->cur_mpu401_irq = 7; + break; + case 3: + ymf701->cur_mpu401_irq = 9; + break; + case 4: + ymf701->cur_mpu401_irq = 10; + break; + default: + break; + } + switch ((val >> 5) & 0x3) { + case 0: + ymf701->cur_mpu401_addr = 0x330; + break; + case 1: + ymf701->cur_mpu401_addr = 0x332; + break; + case 2: + ymf701->cur_mpu401_addr = 0x334; + break; + case 3: + ymf701->cur_mpu401_addr = 0x300; + break; + default: + break; + } + mpu401_change_addr(ymf701->mpu, ymf701->cur_mpu401_addr); + mpu401_setirq(ymf701->mpu, ymf701->cur_mpu401_irq); + gameport_remap(ymf701->gameport, (ymf701->regs[3] & 0x1) ? 0x200 : 0x00); + break; + case 0x04: /* LSI Version Register, on a real Intel Ruby board this is always 0 */ + break; + default: + break; + } + ymf701->passwd_phase = 0x02; + ymf701_log(ymf701->log, "Passwd phase 2\n"); + default: + break; + } + } + ymf701_log(ymf701->log, "Write: addr = %02X, val = %02X\n", addr, val); + if ((ymf701->reg_enabled) && (ymf701->passwd_phase == 0x02)) { + ymf701->reg_enabled = 0; + ymf701->passwd_phase = 0x00; + ymf701_log(ymf701->log, "Disabling reg access\n"); + } + if ((addr == 0xF86) && (val == 0x1D) && (!ymf701->reg_enabled)) { + ymf701->reg_enabled = 1; + ymf701_log(ymf701->log, "Enabling reg access\n"); + } +} + +static uint8_t +ymf701_reg_read(uint16_t addr, void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + uint8_t temp = 0xFF; + + if (ymf701->reg_enabled) { + switch (addr) { + case 0xF86: + temp = ymf701->index; + break; + case 0xF87: + temp = ymf701->regs[ymf701->index]; + /* Only goes into phase 2 on data reads? */ + ymf701->passwd_phase = 0x02; + ymf701_log(ymf701->log, "Passwd phase 2\n"); + break; + default: + break; + } + ymf701_log(ymf701->log, "Read with reg access enabled:\n"); + ymf701_log(ymf701->log, "addr = %02X, ret = %02X\n", addr, temp); + } + if ((ymf701->reg_enabled) && (ymf701->passwd_phase == 0x02)) { + ymf701->reg_enabled = 0; + ymf701->passwd_phase = 0x00; + ymf701_log(ymf701->log, "Disabling reg access\n"); + } + ymf701_log(ymf701->log, "Read: addr = %02X, ret = %02X\n", addr, temp); + return temp; +} + +static void * +ymf701_init(const device_t *info) +{ + ymf701_t *ymf701 = calloc(1, sizeof(ymf701_t)); + + ymf701->type = info->local & 0xFF; + + ymf701->cur_wss_addr = 0x530; + ymf701->cur_mode = 0; + ymf701->cur_addr = 0x220; + ymf701->cur_irq = 5; + ymf701->cur_wss_enabled = 0; + ymf701->cur_dma = 1; + ymf701->cur_mpu401_irq = 9; + ymf701->cur_mpu401_addr = 0x330; + ymf701->cur_mpu401_enabled = 1; + ymf701->cur_wss_dma = 0; + ymf701->cur_wss_irq = 11; + + ymf701->regs[0] = 0xFF; + ymf701->regs[1] = 0x24; + ymf701->regs[2] = 0x46; + ymf701->regs[3] = 0x87; + ymf701->regs[4] = 0x00; + + ymf701->log = log_open("YMF701"); + + ymf701->gameport = gameport_add(&gameport_pnp_device); + gameport_remap(ymf701->gameport, (ymf701->regs[3] & 0x1) ? 0x200 : 0x00); + + ad1848_init(&ymf701->ad1848, AD1848_TYPE_CS4231); + + ad1848_setirq(&ymf701->ad1848, ymf701->cur_wss_irq); + ad1848_setdma(&ymf701->ad1848, ymf701->cur_wss_dma); + + io_sethandler(0xF86, 2, ymf701_reg_read, NULL, NULL, ymf701_reg_write, NULL, NULL, ymf701); + + io_sethandler(ymf701->cur_wss_addr, 0x0004, ymf701_wss_read, NULL, NULL, ymf701_wss_write, NULL, NULL, ymf701); + io_sethandler(ymf701->cur_wss_addr + 0x0004, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &ymf701->ad1848); + + ymf701->sb = calloc(1, sizeof(sb_t)); + ymf701->sb->opl_enabled = 1; + + sb_dsp_set_real_opl(&ymf701->sb->dsp, 1); + sb_dsp_init(&ymf701->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, ymf701); + sb_dsp_setaddr(&ymf701->sb->dsp, ymf701->cur_addr); + sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_irq); + sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_dma); + sb_ct1345_mixer_reset(ymf701->sb); + + ymf701->sb->opl_mixer = ymf701; + ymf701->sb->opl_mix = ymf701_filter_opl; + + fm_driver_get(FM_YMF262, &ymf701->sb->opl); + io_sethandler(ymf701->cur_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(ymf701->cur_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(0x0388, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + + io_sethandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + + sound_add_handler(ymf701_get_buffer, ymf701); + music_add_handler(sb_get_music_buffer_sbpro, ymf701->sb); + ad1848_is_opl3sa(&ymf701->ad1848); + //sound_set_cd_audio_filter(sbpro_filter_cd_audio, ymf701->sb); /* CD audio filter for the default context */ + sound_set_cd_audio_filter(ad1848_filter_cd_audio, &ymf701->ad1848); + + ymf701->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); + mpu401_init(ymf701->mpu, ymf701->cur_mpu401_addr, ymf701->cur_mpu401_irq, M_UART, device_get_config_int("receive_input401")); + + if (device_get_config_int("receive_input")) + midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &ymf701->sb->dsp); + + return ymf701; +} + +static void +ymf701_close(void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + + if (ymf701->log != NULL) { + log_close(ymf701->log); + ymf701->log = NULL; + } + + sb_close(ymf701->sb); + free(ymf701->mpu); + free(priv); +} + +static void +ymf701_speed_changed(void *priv) +{ + ymf701_t *ymf701 = (ymf701_t *) priv; + + ad1848_speed_changed(&ymf701->ad1848); + sb_speed_changed(ymf701->sb); +} + +static const device_config_t ymf701_config[] = { + // clang-format off + { + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { + .name = "receive_input401", + .description = "Receive MIDI input (MPU-401)", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ymf701_device = { + .name = "Yamaha YMF-701 (OPL3-SA)", + .internal_name = "ymf701", + .flags = DEVICE_ISA16, + .local = 0x00, + .init = ymf701_init, + .close = ymf701_close, + .reset = NULL, + .available = NULL, + .speed_changed = ymf701_speed_changed, + .force_redraw = NULL, + .config = ymf701_config +}; diff --git a/src/sound/sound.c b/src/sound/sound.c index c81dc47b0..f8239b298 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -158,6 +158,7 @@ static const SOUND_CARD sound_cards[] = { { &sb_vibra16s_device }, { &sb_vibra16xv_device }, { &wss_device }, + { &ymf701_device }, /* MCA */ { &adlib_mca_device }, { &ess_chipchat_16_mca_device }, From 2141353592d91a122ec336771be0bd3d14523b29 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Sep 2025 00:44:16 +0200 Subject: [PATCH 023/138] Minor cleanup on 53c9x code (September 7th, 2025) --- src/scsi/scsi_pcscsi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 04c188705..2c73066a1 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1274,7 +1274,7 @@ esp_command_complete(void *priv, uint32_t status) static void esp_timer_on(esp_t *dev, scsi_device_t *sd, double p) { - if ((dev->rregs[ESP_CFG3] & 0x18) == 0x18) { + if ((dev->wregs[ESP_CFG3] & 0x18) == 0x18) { /* Fast SCSI: 10000000 bytes per second */ dev->period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); } else { @@ -1537,11 +1537,11 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_pci_soft_reset(dev); break; case CMD_BUSRESET: - esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); + esp_log("ESP Bus Reset val=%02x.\n", (dev->wregs[ESP_CFG1] & CFG1_RESREPT)); for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { + if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); @@ -1579,7 +1579,7 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_raise_irq(dev); break; case CMD_PAD: - esp_log("val = %02X\n", val); + esp_log("PAD=%02X\n", val); timer_stop(&dev->timer); timer_on_auto(&dev->timer, dev->period); esp_log("ESP Transfer Pad\n"); @@ -2214,7 +2214,8 @@ esp_pci_reset(void *priv) esp_pci_soft_reset(dev); esp_log("PCI Reset.\n"); - } + } else + esp_log("NULL.\n"); } static void * From a6becc31580b370d0b06cc002731a42c7a245d37 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Sep 2025 01:01:03 +0200 Subject: [PATCH 024/138] Major video changes and fixes of the day (September 7th, 2025) 1. Rewritten Sierra SC1502x RAMDAC code to match the manual, allowing proper BPP selection on cards which use it. 2. Added a reference clock variable for cards which have a different default one (ELSA cards namely) on the ICD2061 code. 3. Reorganized RAMDAC selection in the S3 code. 4. Added more ELSA Winner cards based on the 928 chip (ELSA Winner 2000 ISA, 1000 VLB and 1000 PCI based on 928PCI). 5. The horizontal override is now also enabled for ELSA Winner 1000 (928 VLB and PCI) cards with 32bpp set, to avoid wrong horizontal displays. 6. LFB in PCI mode doesn't have the same limitations as on VLB or ISA. 7. Added more hdisp adjustments for the Elsa cards. 8. Mono patterns are now more correct in ROPBLT acceleration (command 14), fixes blackness in some instances of Win95 (matching the 968 manual). 9. Minor cleanup on the accel registers. --- src/include/86box/vid_svga.h | 4 + src/include/86box/video.h | 11 +- src/video/clockgen/vid_clockgen_icd2061.c | 21 +- src/video/ramdac/vid_ramdac_sc1502x.c | 261 ++++++--- src/video/vid_s3.c | 647 ++++++++++++++++++---- src/video/vid_table.c | 5 +- 6 files changed, 757 insertions(+), 192 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index b588a3daf..a66dd8c03 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -449,6 +449,7 @@ extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float r extern void icd2061_write(void *priv, int val); extern float icd2061_getclock(int clock, void *priv); +extern void icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock); /* The code is the same, the #define's are so that the correct name can be used. */ # define ics9161_write icd2061_write @@ -465,6 +466,8 @@ extern uint8_t sc1148x_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svg extern void sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga); extern uint8_t sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga); +extern void sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); +extern uint8_t sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); extern void sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga); extern uint8_t sdac_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga); @@ -516,6 +519,7 @@ extern const device_t sc11487_ramdac_device; extern const device_t sc11486_ramdac_device; extern const device_t sc11484_nors2_ramdac_device; extern const device_t sc1502x_ramdac_device; +extern const device_t sc1502x_rs2_ramdac_device; extern const device_t sdac_ramdac_device; extern const device_t stg_ramdac_device; extern const device_t tkd8001_ramdac_device; diff --git a/src/include/86box/video.h b/src/include/86box/video.h index b5be81bbb..81424dbcb 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -412,7 +412,7 @@ extern const device_t cga_pravetz_device; /* Compaq CGA */ extern const device_t compaq_cga_device; extern const device_t compaq_cga_2_device; -extern const device_t compaq_plasma_device; +extern const device_t compaq_plasma_device; /* Olivetti OGC */ extern const device_t ogc_device; @@ -513,8 +513,11 @@ extern const device_t realtek_rtg3106_device; extern const device_t s3_orchid_86c911_isa_device; extern const device_t s3_diamond_stealth_vram_isa_device; extern const device_t s3_ami_86c924_isa_device; +extern const device_t s3_elsa_winner1000_86c928_vlb_device; +extern const device_t s3_elsa_winner2000_86c928_isa_device; extern const device_t s3_metheus_86c928_isa_device; extern const device_t s3_metheus_86c928_vlb_device; +extern const device_t s3_elsa_winner1000_86c928_pci_device; extern const device_t s3_spea_mercury_lite_86c928_pci_device; extern const device_t s3_spea_mirage_86c801_isa_device; extern const device_t s3_winner1000_805_isa_device; @@ -635,9 +638,9 @@ extern const device_t wy700_device; extern const device_t v6355d_device; /* Tandy */ -extern const device_t tandy_1000_video_device; -extern const device_t tandy_1000hx_video_device; -extern const device_t tandy_1000sl_video_device; +extern const device_t tandy_1000_video_device; +extern const device_t tandy_1000hx_video_device; +extern const device_t tandy_1000sl_video_device; #endif diff --git a/src/video/clockgen/vid_clockgen_icd2061.c b/src/video/clockgen/vid_clockgen_icd2061.c index 7b80a5484..f1925e769 100644 --- a/src/video/clockgen/vid_clockgen_icd2061.c +++ b/src/video/clockgen/vid_clockgen_icd2061.c @@ -29,10 +29,15 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/video.h> +#include <86box/vid_svga.h> #include <86box/plat_unused.h> typedef struct icd2061_t { - float freq[3]; + float freq[3]; + float ref_clock; int count; int bit_count; @@ -121,7 +126,7 @@ icd2061_write(void *priv, int val) q = qa + 2; /* Q (ICD2061) / M (ICS9161) */ ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */ - icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * 14318184.0f; + icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * icd2061->ref_clock; icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]); } else if (a == 6) { @@ -149,12 +154,24 @@ icd2061_getclock(int clock, void *priv) return icd2061->freq[clock]; } +void +icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock) +{ + icd2061_t *icd2061 = (icd2061_t *) priv; + + if (icd2061) + icd2061->ref_clock = ref_clock; + + svga_recalctimings(svga); +} + static void * icd2061_init(UNUSED(const device_t *info)) { icd2061_t *icd2061 = (icd2061_t *) malloc(sizeof(icd2061_t)); memset(icd2061, 0, sizeof(icd2061_t)); + icd2061->ref_clock = 14318184.0f; icd2061->freq[0] = 25175000.0; icd2061->freq[1] = 28322000.0; icd2061->freq[2] = 28322000.0; diff --git a/src/video/ramdac/vid_ramdac_sc1502x.c b/src/video/ramdac/vid_ramdac_sc1502x.c index 1c7d4014d..4fc603ee9 100644 --- a/src/video/ramdac/vid_ramdac_sc1502x.c +++ b/src/video/ramdac/vid_ramdac_sc1502x.c @@ -33,65 +33,32 @@ typedef struct sc1502x_ramdac_t { int state; + int use_rs2; uint8_t ctrl; uint8_t idx; uint8_t regs[256]; uint32_t pixel_mask; - uint8_t enable_ext; } sc1502x_ramdac_t; static void -sc1502x_ramdac_bpp(uint8_t val, sc1502x_ramdac_t *ramdac, svga_t *svga) +sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga) { - int oldbpp = 0; - if (val == 0xff) - return; - ramdac->ctrl = val; - oldbpp = svga->bpp; - switch ((val & 1) | ((val & 0xc0) >> 5)) { - case 0: - svga->bpp = 8; - break; - case 2: - case 3: - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - break; - case 4: - case 5: - svga->bpp = 15; - break; - case 6: + int oldbpp = svga->bpp; + if (ramdac->ctrl & 0x80) { + if (ramdac->ctrl & 0x40) { svga->bpp = 16; - break; - case 7: - if (val & 4) { - switch (val & 0x20) { - case 0x00: - svga->bpp = 32; - break; - case 0x20: - svga->bpp = 24; - break; - - default: - break; - } - } else - svga->bpp = 16; - break; - - default: - break; + } else + svga->bpp = 15; + } else { + if (ramdac->ctrl & 0x40) { + if (ramdac->regs[0x10] & 0x01) + svga->bpp = 32; + else if (ramdac->ctrl & 0x20) + svga->bpp = 24; + else + svga->bpp = 32; + } else + svga->bpp = 8; } if (oldbpp != svga->bpp) svga_recalctimings(svga); @@ -104,29 +71,30 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) switch (addr) { case 0x3C6: - if (ramdac->state == 0) - ramdac->enable_ext = (val == 0x10); - - if (ramdac->state == 4) { + if ((ramdac->state == 4) || (ramdac->ctrl & 0x10)) { ramdac->state = 0; - sc1502x_ramdac_bpp(val, ramdac, svga); + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); return; } ramdac->state = 0; + svga_out(addr, val, svga); break; case 0x3C7: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) ramdac->idx = val; - return; - } + else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 8: - ramdac->regs[ramdac->idx] = val; - svga_set_ramdac_type(svga, (ramdac->regs[ramdac->idx] & 1) ? RAMDAC_8BIT : RAMDAC_6BIT); + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; break; case 0x0d: ramdac->pixel_mask = val & svga->dac_mask; @@ -137,24 +105,96 @@ sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *priv, svga_t *svga) case 0x0f: ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; default: ramdac->regs[ramdac->idx] = val; break; } - return; - } + } else + svga_out(addr, val, svga); + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) - return; ramdac->state = 0; + svga_out(addr, val, svga); break; default: break; } - svga_out(addr, val, svga); +} + +void +sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 8: + ramdac->regs[8] = val; + svga->ramdac_type = (val & 0x01) ? RAMDAC_8BIT : RAMDAC_6BIT; + break; + case 0x0d: + ramdac->pixel_mask = val & svga->dac_mask; + break; + case 0x0e: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 8); + break; + case 0x0f: + ramdac->pixel_mask |= ((val & svga->dac_mask) << 16); + break; + case 0x10: + ramdac->regs[0x10] = val; + sc1502x_ramdac_bpp(ramdac, svga); + break; + default: + ramdac->regs[ramdac->idx] = val; + break; + } + } else + svga_out(addr, val, svga); + break; + case 0x01: + svga_out(addr, val, svga); + break; + case 0x02: + if (ramdac->ctrl & 0x10) { + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + } else + svga_out(addr, val, svga); + break; + case 0x03: + if (ramdac->ctrl & 0x10) + ramdac->idx = val; + else + svga_out(addr, val, svga); + break; + case 0x04: + case 0x05: + case 0x07: + svga_out(addr, val, svga); + break; + case 0x06: + ramdac->ctrl = val; + if (val != 0xff) + sc1502x_ramdac_bpp(ramdac, svga); + break; + + default: + svga_out(addr, val, svga); + break; + } } uint8_t @@ -166,8 +206,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) switch (addr) { case 0x3C6: if (ramdac->state == 4) { - ramdac->state = 0; - temp = ramdac->ctrl; + temp = ramdac->ctrl; break; } ramdac->state++; @@ -176,7 +215,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) ramdac->state = 0; break; case 0x3C8: - if (ramdac->enable_ext) { + if (ramdac->ctrl & 0x10) { switch (ramdac->idx) { case 9: temp = 0x53; @@ -203,14 +242,72 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) temp = ramdac->regs[ramdac->idx]; break; } - } else - ramdac->state = 0; + } + ramdac->state = 0; break; case 0x3C9: - if (ramdac->enable_ext) + if (ramdac->ctrl & 0x10) temp = ramdac->idx; - else - ramdac->state = 0; + + ramdac->state = 0; + break; + + default: + break; + } + + return temp; +} + +uint8_t +sc1502x_rs2_ramdac_in(uint16_t addr, int rs2, void *priv, svga_t *svga) +{ + sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv; + uint8_t rs = (addr & 0x03); + uint8_t temp = svga_in(addr, svga); + rs |= ((!!rs2) << 2); + + switch (rs) { + case 0x00: + if (ramdac->ctrl & 0x10) { + switch (ramdac->idx) { + case 9: + temp = 0x53; + break; + case 0x0a: + temp = 0x3a; + break; + case 0x0b: + temp = 0xb1; + break; + case 0x0c: + temp = 0x41; + break; + case 0x0d: + temp = ramdac->pixel_mask & 0xff; + break; + case 0x0e: + temp = ramdac->pixel_mask >> 8; + break; + case 0x0f: + temp = ramdac->pixel_mask >> 16; + break; + default: + temp = ramdac->regs[ramdac->idx]; + break; + } + } + break; + case 0x01: + if (ramdac->ctrl & 0x10) + temp = ramdac->idx; + break; + case 0x02: + if (ramdac->ctrl & 0x10) + temp = ramdac->ctrl; + break; + case 0x06: + temp = ramdac->ctrl; break; default: @@ -221,7 +318,7 @@ sc1502x_ramdac_in(uint16_t addr, void *priv, svga_t *svga) } static void * -sc1502x_ramdac_init(UNUSED(const device_t *info)) +sc1502x_ramdac_init(const device_t *info) { sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) malloc(sizeof(sc1502x_ramdac_t)); memset(ramdac, 0, sizeof(sc1502x_ramdac_t)); @@ -254,3 +351,17 @@ const device_t sc1502x_ramdac_device = { .force_redraw = NULL, .config = NULL }; + +const device_t sc1502x_rs2_ramdac_device = { + .name = "Sierra SC1502x RAMDAC with RS2", + .internal_name = "sc1502x_rs2_ramdac", + .flags = 0, + .local = 1, + .init = sc1502x_ramdac_init, + .close = sc1502x_ramdac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fbf329e84..870221742 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -49,6 +49,9 @@ #define ROM_DIAMOND_STEALTH_VRAM "roms/video/s3/Diamond Stealth VRAM BIOS v2.31 U14.BIN" #define ROM_AMI_86C924 "roms/video/s3/S3924AMI.BIN" #define ROM_METHEUS_86C928 "roms/video/s3/928.VBI" +#define ROM_ELSAWIN1KVL_86C928 "roms/video/s3/ELSA_Winner_XHR_1000VL.BIN" +#define ROM_ELSAWIN1KPCI_86C928 "roms/video/s3/ELSA_Winner_10000_PCI_BIOS_3.04.02.BIN" +#define ROM_ELSAWIN2K_86C928 "roms/video/s3/elsa-winner-2000-vga-bios-v1-02-03-66b7554c706d6962736994.bin" #define ROM_SPEA_MERCURY_LITE_PCI "roms/video/s3/SPEAVGA.VBI" #define ROM_SPEA_MIRAGE_86C801 "roms/video/s3/V7MIRAGE.VBI" #define ROM_SPEA_MIRAGE_86C805 "roms/video/s3/86c805pspeavlbus.BIN" @@ -98,6 +101,9 @@ enum { S3_PHOENIX_86C805, S3_ORCHID_86C911, S3_METHEUS_86C928, + S3_ELSAWIN1K_86C928, + S3_ELSAWIN1KPCI_86C928, + S3_ELSAWIN2K_86C928, S3_AMI_86C924, S3_TRIO64V2_DX, S3_TRIO64V2_DX_ONBOARD, @@ -191,8 +197,19 @@ enum { FIFO_OUT_DWORD = (0x06 << 24) }; -typedef struct -{ +typedef enum { + BUILT_IN = 0, + SC1148X, + SC1502X, + ATT49X, + ATT498, + BT48X, + IBM_RGB, + S3_SDAC, + TVP3026 +} s3_ramdac_type; + +typedef struct { uint32_t addr_type; uint32_t val; } fifo_entry_t; @@ -204,6 +221,8 @@ typedef struct s3_t { mem_mapping_t new_mmio_mapping; int elsa_eeprom; + s3_ramdac_type ramdac_type; + uint8_t has_bios; rom_t bios_rom; @@ -1519,14 +1538,17 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xd148: case 0xd2e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0xff00) | val; break; case 0xd149: case 0xd2e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); s3->accel.ropmix = (s3->accel.ropmix & 0x00ff) | (val << 8); break; case 0xe548: case 0xe6e8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); @@ -1537,6 +1559,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe549: case 0xe6e9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); @@ -1550,6 +1573,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54a: case 0xe6ea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1561,6 +1585,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe54b: case 0xe6eb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1578,7 +1603,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe949: case 0xeae9: - s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_y = (s3->accel.pat_y & 0xff) | ((val & 0x0f) << 8); break; case 0xe94a: case 0xeaea: @@ -1586,10 +1611,11 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe94b: case 0xeaeb: - s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x1f) << 8); + s3->accel.pat_x = (s3->accel.pat_x & 0xff) | ((val & 0x0f) << 8); break; case 0xed48: case 0xeee8: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); @@ -1600,6 +1626,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed49: case 0xeee9: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->bpp == 3) { if ((s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); @@ -1613,6 +1640,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4a: case 0xeeea: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); else if (s3->bpp == 3) { @@ -1624,6 +1652,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed4b: case 0xeeeb: + s3_log("[%04X:%08X] OUT PORTB=%04x, val=%02x, CMD=%04x, C(%d,%d).\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y); if (s3->accel.multifunc[0xe] & 0x200) s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); else if (s3->bpp == 3) { @@ -1977,29 +2006,39 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8120: + addr = 0xa2e8; + break; case 0x8122: /*BKGD_COLOR*/ - WRITE8(addr, s3->accel.bkgd_color, val); - return; + addr = 0xa2ea; + break; case 0x8124: + addr = 0xa6e8; + break; case 0x8126: /*FRGD_COLOR*/ - WRITE8(addr, s3->accel.frgd_color, val); - return; + addr = 0xa6ea; + break; case 0x8128: + addr = 0xaae8; + break; case 0x812a: /*WRT_MASK*/ - WRITE8(addr, s3->accel.wrt_mask, val); - return; + addr = 0xaaea; + break; case 0x812c: + addr = 0xaee8; + break; case 0x812e: /*RD_MASK*/ - WRITE8(addr, s3->accel.rd_mask, val); - return; + addr = 0xaeea; + break; case 0x8130: + addr = 0xb2e8; + break; case 0x8132: /*COLOR_CMP*/ - WRITE8(addr, s3->accel.color_cmp, val); - return; + addr = 0xb2ea; + break; case 0x8134: addr = 0xb6e8; @@ -2056,9 +2095,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x8164: + addr = 0xe6e8; + break; case 0x8166: - WRITE8(addr, s3->accel.pat_bg_color, val); - return; + addr = 0xe6ea; + break; case 0x8168: addr = 0xeae8; @@ -2068,9 +2109,11 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) break; case 0x816c: + addr = 0xeee8; + break; case 0x816e: - WRITE8(addr, s3->accel.pat_fg_color, val); - return; + addr = 0xeeea; + break; default: break; @@ -2235,7 +2278,7 @@ s3_vblank_start(svga_t *svga) static uint32_t s3_hwcursor_convert_addr(svga_t *svga) { - if ((svga->bpp == 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { + if ((svga->bpp >= 8) && (((svga->gdcreg[5] & 0x60) == 0x20) || (svga->crtc[0x3a] & 0x10)) && (svga->crtc[0x45] & 0x10)) { if (svga->crtc[0x3a] & 0x10) return ((svga->hwcursor_latch.addr & 0xfffff1ff) | ((svga->hwcursor_latch.addr & 0x200) << 2)) | 0x600; else if ((svga->gdcreg[5] & 0x60) == 0x20) @@ -3019,27 +3062,38 @@ s3_out(uint16_t addr, uint8_t val, void *priv) else rs2 = (svga->crtc[0x55] & 0x01); // rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - svga_out(addr, val, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && - ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) - att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) { - sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); - } else if (s3->card_type == S3_NUMBER9_9FX_531) - att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - sc1502x_ramdac_out(addr, val, svga->ramdac, svga); - else - sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + switch (s3->ramdac_type) { + case BUILT_IN: + default: + svga_out(addr, val, svga); + break; + case SC1148X: + sc1148x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case SC1502X: + sc1502x_ramdac_out(addr, val, svga->ramdac, svga); + break; + case ATT49X: + att49x_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case ATT498: + att498_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case BT48X: + rs3 = !!(svga->crtc[0x55] & 0x02); + bt48x_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + case IBM_RGB: + ibm_rgb528_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case S3_SDAC: + sdac_ramdac_out(addr, rs2, val, svga->ramdac, svga); + break; + case TVP3026: + rs3 = !!(svga->crtc[0x55] & 0x02); + tvp3026_ramdac_out(addr, rs2, rs3, val, svga->ramdac, svga); + break; + } return; case 0x3D4: @@ -3084,7 +3138,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x5c: if (s3->elsa_eeprom) nmc93cxx_eeprom_write(s3->eeprom, !!(val & 0x80), !!(val & 0x40), !!(val & 0x10)); - if (s3->card_type == S3_PHOENIX_VISION868 || s3->card_type == S3_PHOENIX_VISION968) { + if ((s3->card_type == S3_PHOENIX_VISION868) || (s3->card_type == S3_PHOENIX_VISION968)) { if ((val & 0x20) && (!(svga->crtc[0x55] & 0x01) && !(svga->crtc[0x43] & 2))) svga->dac_addr |= 0x20; } else if (s3->card_type == S3_MIROVIDEO40SV_ERGO_968) { @@ -3136,6 +3190,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if ((s3->chip == S3_VISION964) || (s3->chip == S3_VISION968)) break; svga->hwcursor.ena = val & 1; + s3_log("Write CRTC45=%02x.\n", val); break; case 0x46: case 0x47: @@ -3213,12 +3268,14 @@ s3_out(uint16_t addr, uint8_t val, void *priv) case 0x55: s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); if (s3->chip == S3_86C928) { - if (val & 0x28) { - svga->hwcursor_draw = NULL; - svga->dac_hwcursor_draw = bt48x_hwcursor_draw; - } else { - svga->hwcursor_draw = s3_hwcursor_draw; - svga->dac_hwcursor_draw = NULL; + if (s3->ramdac_type == BT48X) { + if (val & 0x28) { + svga->hwcursor_draw = NULL; + svga->dac_hwcursor_draw = bt48x_hwcursor_draw; + } else { + svga->hwcursor_draw = s3_hwcursor_draw; + svga->dac_hwcursor_draw = NULL; + } } } break; @@ -3345,32 +3402,43 @@ s3_in(uint16_t addr, void *priv) case 0x3c8: case 0x3c9: rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); - if (s3->chip >= S3_TRIO32) - return svga_in(addr, svga); - else if ((s3->chip == S3_VISION964 && s3->card_type != S3_ELSAWIN2KPROX_964) || (s3->chip == S3_86C928)) { - if (s3->chip == S3_86C928) - rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ - else + switch (s3->ramdac_type) { + case BUILT_IN: + default: + temp = svga_in(addr, svga); + break; + case SC1148X: + temp = sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case SC1502X: + temp = sc1502x_ramdac_in(addr, svga->ramdac, svga); + break; + case ATT49X: + temp = att49x_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case ATT498: + temp = att498_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case BT48X: + if (s3->chip == S3_86C928) + rs3 = !!(svga->crtc[0x55] & 0x28) || !!(svga->crtc[0x45] & 0x20) || !!(svga->crtc[0x55] & 0x02); /*Quite insane but Win95's S3 driver wants it set at all costs for 8bpp+ mode*/ + else + rs3 = !!(svga->crtc[0x55] & 0x02); + + temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + case IBM_RGB: + temp = ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case S3_SDAC: + temp = sdac_ramdac_in(addr, rs2, svga->ramdac, svga); + break; + case TVP3026: rs3 = !!(svga->crtc[0x55] & 0x02); - temp = bt48x_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - return temp; - } else if ((s3->chip == S3_VISION964 && s3->card_type == S3_ELSAWIN2KPROX_964) || (s3->chip == S3_VISION968 && (s3->card_type == S3_DIAMOND_STEALTH64_968 || s3->card_type == S3_ELSAWIN2KPROX || s3->card_type == S3_PHOENIX_VISION968 || s3->card_type == S3_NUMBER9_9FX_771))) - return ibm_rgb528_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip == S3_VISION968 && (s3->card_type == S3_SPEA_MERCURY_P64V || s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) { - rs3 = !!(svga->crtc[0x55] & 0x02); - return tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); - } else if (((s3->chip == S3_86C801) || (s3->chip == S3_86C805)) && - ((s3->card_type != S3_MIROCRYSTAL10SD_805) && (s3->card_type != S3_MIROCRYSTAL8S_805))) - return att49x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->chip <= S3_86C924) - return sc1148x_ramdac_in(addr, rs2, svga->ramdac, svga); - else if (s3->card_type == S3_NUMBER9_9FX_531) - return att498_ramdac_in(addr, rs2, svga->ramdac, svga); - else if ((s3->chip == S3_86C928PCI) && (s3->card_type == S3_SPEA_MERCURY_LITE_PCI)) - return sc1502x_ramdac_in(addr, svga->ramdac, svga); - else - return sdac_ramdac_in(addr, rs2, svga->ramdac, svga); - break; + temp = tvp3026_ramdac_in(addr, rs2, rs3, svga->ramdac, svga); + break; + } + return temp; case 0x3d4: return svga->crtcreg; @@ -3650,20 +3718,21 @@ s3_recalctimings(svga_t *svga) svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); - if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { - if (s3->card_type == S3_ELSAWIN2KPROX_964) - ibm_rgb528_recalctimings(svga->ramdac, svga); - else { + switch (s3->ramdac_type) { + case BT48X: bt48x_recalctimings(svga->ramdac, svga); svga->interlace |= (!!(svga->crtc[0x42] & 0x20)); - } - } else if (s3->chip == S3_VISION968) { - if ((s3->card_type == S3_SPEA_MERCURY_P64V) || (s3->card_type == S3_MIROVIDEO40SV_ERGO_968)) - tvp3026_recalctimings(svga->ramdac, svga); - else + break; + case IBM_RGB: ibm_rgb528_recalctimings(svga->ramdac, svga); - } else - svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + case TVP3026: + tvp3026_recalctimings(svga->ramdac, svga); + break; + default: + svga->interlace = !!(svga->crtc[0x42] & 0x20); + break; + } if (s3->chip >= S3_TRIO32) { switch (svga->crtc[0x67] >> 4) { @@ -3797,13 +3866,127 @@ s3_recalctimings(svga_t *svga) break; } break; - + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + if (s3->ramdac_type == BT48X) { + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + } + break; + } + break; + default: + break; + } + break; default: break; } break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + switch (s3->width) { + case 1024: + switch (svga->hdisp) { + case 256: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 512: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 1280: /*Account for the 1280x1024 resolution*/ + switch (svga->hdisp) { + case 320: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ + switch (svga->hdisp) { + case 320: + case 384: + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + break; + case 576: + case 640: + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + break; + default: + break; + } + break; + default: + break; + } + break; + case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -3961,6 +4144,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -3968,6 +4173,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4157,6 +4366,28 @@ s3_recalctimings(svga_t *svga) break; } break; + case S3_ELSAWIN1K_86C928: + case S3_ELSAWIN2K_86C928: + switch (s3->width) { + case 2048: + if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + break; + default: + if (s3->ramdac_type == BT48X) + svga->clock /= 2.0; + else if (s3->ramdac_type == SC1502X) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } + break; + } + break; default: break; @@ -4164,6 +4395,10 @@ s3_recalctimings(svga_t *svga) break; case S3_86C928PCI: switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + break; case S3_SPEA_MERCURY_LITE_PCI: switch (s3->width) { case 640: @@ -4365,11 +4600,32 @@ s3_recalctimings(svga_t *svga) case 32: svga->render = svga_render_32bpp_highres; switch (s3->chip) { + case S3_86C928: + switch (s3->card_type) { + case S3_ELSAWIN1K_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; + case S3_86C928PCI: + switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + svga->clock *= 2.0; + break; + default: + break; + } + break; case S3_VISION864: svga->hdisp >>= 2; svga->dots_per_clock >>= 2; break; - case S3_VISION868: switch (s3->card_type) { case S3_PHOENIX_VISION868: @@ -4499,7 +4755,8 @@ s3_recalctimings(svga_t *svga) } } - if ((s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) + if ((((s3->card_type == S3_ELSAWIN1K_86C928) || (s3->card_type == S3_ELSAWIN1KPCI_86C928)) && (svga->bpp == 32)) || + (s3->chip == S3_TRIO32) || (s3->chip == S3_TRIO64) || (s3->chip == S3_VISION864) || (s3->chip == S3_VISION868) || (s3->chip == S3_VISION968)) svga->hoverride = 1; else svga->hoverride = 0; @@ -4771,7 +5028,7 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { if (s3->vlb) s3->linear_base &= 0x03ffffff; - else + else if (!s3->pci) s3->linear_base &= 0x00ffffff; } if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { @@ -7599,6 +7856,7 @@ polygon_setup(s3_t *s3) old_dest_dat = dest_dat; \ ROPMIX_READ(dest_dat, pat_dat, src_dat); \ out = (out & s3->accel.wrt_mask) | (old_dest_dat & ~s3->accel.wrt_mask); \ + out &= 0xFFFFFF; \ } #define WRITE(addr, dat) \ @@ -9543,6 +9801,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; case 14: /*ROPBlt (Vision868/968 only)*/ + ; + uint32_t mono_pattern[64] = { 0 }; if (s3->chip != S3_VISION968 && s3->chip != S3_VISION868) break; @@ -9552,11 +9812,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.sy = s3->accel.multifunc[0] & 0xfff; s3->accel.dx = s3->accel.destx_distp & 0xfff; - if (s3->accel.destx_distp & 0x1000) - s3->accel.dx |= ~0xfff; s3->accel.dy = s3->accel.desty_axstp & 0xfff; - if (s3->accel.desty_axstp & 0x1000) - s3->accel.dy |= ~0xfff; s3->accel.cx = s3->accel.cur_x & 0xfff; s3->accel.cy = s3->accel.cur_y & 0xfff; @@ -9567,13 +9823,35 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi s3->accel.dest = dstbase + (s3->accel.dy * s3->width); s3->accel.src = srcbase + (s3->accel.cy * s3->width); s3->accel.pattern = (s3->accel.py * s3->width); + s3_log("ROPBLT=%04x, PIXCntl=%04x, Misc1=%04x, PATBKGDCOL=%08x, PATFRGDCOL=%08x, COLBKGDCOL=%08x, COLFRGDCOL=%08x, PX=%d, PY=%d, DX=%d, DY=%d, CX=%d, CY=%d, FRGDSEL=%x, BKGDSEL=%x, RDMASK=%08x, WRTMASK=%08x, ROPMIX=%03x, pitch=%d.\n", s3->accel.cmd, s3->accel.multifunc[0xa], s3->accel.multifunc[0xe], s3->accel.pat_bg_color, s3->accel.pat_fg_color, s3->accel.bkgd_color, s3->accel.frgd_color, s3->accel.px, s3->accel.py, s3->accel.dx, s3->accel.dy, s3->accel.cx, s3->accel.cy, frgd_mix, bkgd_mix, s3->accel.rd_mask, s3->accel.wrt_mask, s3->accel.ropmix, s3->width); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + if (s3->accel.ropmix & 0x100) { + int x; + int y; + switch (s3->accel.cmd & 0x600) { + case 0x000: + case 0x600: + mix_dat &= 0xff; + break; + case 0x200: + mix_dat &= 0xffff; + break; + default: + break; + } + + for (y = 0; y < 8; y++) { + for (x = 0; x < 8; x++) { + mono_pattern[y * 8 + (7 - x)] = (mix_dat & (1 << (x + y * 8))) & 0x80000000; + } + } + } while (count-- && s3->accel.sy >= 0) { - if ((s3->accel.dx & 0xfff) >= clip_l && (s3->accel.dx & 0xfff) <= clip_r && (s3->accel.dy & 0xfff) >= clip_t && (s3->accel.dy & 0xfff) <= clip_b) { + if ((s3->accel.dx >= clip_l) && (s3->accel.dx <= clip_r) && (s3->accel.dy >= clip_t) && (s3->accel.dy <= clip_b)) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: src_dat = s3->accel.bkgd_color; @@ -9592,24 +9870,18 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi break; } - if (s3->accel.ropmix & 0x100) { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + if (s3->accel.ropmix & 0x100) { /*Mono pattern used*/ + switch (mono_pattern[(s3->accel.py & 7) * 8 + (s3->accel.px & 7)] ? (frgd_mix & 1) : (bkgd_mix & 1)) { case 0: pat_dat = s3->accel.pat_bg_color; break; case 1: pat_dat = s3->accel.pat_fg_color; break; - case 2: - pat_dat = cpu_dat; - break; - case 3: - READ(s3->accel.pattern + s3->accel.px, pat_dat); - break; - default: break; } + s3_log("MonoMIX=%08x, PX=%d, PY=%d.\n", mix_dat, s3->accel.px & 7, s3->accel.py & 7); } else { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -9645,19 +9917,12 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else update = 1; - if (s3->bpp == 2) { - src_dat &= 0xff; - pat_dat &= 0xff; - } else if (s3->bpp == 1) { - src_dat &= 0xffff; - pat_dat &= 0xffff; - } - if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); ROPMIX + s3_log("Destination=%08x, Source=%08x, Pattern=%08x, OUT=%08x, mix=%08x, count=%d.\n", dest_dat, src_dat, pat_dat, out, mix_dat, count); if (s3->accel.cmd & 0x10) { WRITE(s3->accel.dest + s3->accel.dx, out); } @@ -9666,6 +9931,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi mix_dat <<= 1; mix_dat |= 1; + if (s3->bpp == 0) cpu_dat >>= 8; else @@ -10111,6 +10377,21 @@ s3_init(const device_t *info) else video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); break; + case S3_ELSAWIN1K_86C928: + bios_fn = ROM_ELSAWIN1KVL_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c805); + break; + case S3_ELSAWIN1KPCI_86C928: + bios_fn = ROM_ELSAWIN1KPCI_86C928; + chip = S3_86C928PCI; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c928pci); + break; + case S3_ELSAWIN2K_86C928: + bios_fn = ROM_ELSAWIN2K_86C928; + chip = S3_86C928; + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_s3_86c801); + break; case S3_SPEA_MERCURY_LITE_PCI: bios_fn = ROM_SPEA_MERCURY_LITE_PCI; chip = S3_86C928PCI; @@ -10482,6 +10763,7 @@ s3_init(const device_t *info) s3->accel_start = s3_accel_start; s3->elsa_eeprom = 0; + s3->ramdac_type = BUILT_IN; switch (s3->card_type) { case S3_ORCHID_86C911: @@ -10494,6 +10776,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; if (s3->card_type == S3_ORCHID_86C911) { svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; @@ -10501,6 +10784,7 @@ s3_init(const device_t *info) /* DCS2824-0 = Diamond ICD2061A-compatible. */ svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } break; @@ -10513,6 +10797,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->ramdac = device_add(&sc11483_ramdac_device); + s3->ramdac_type = SC1148X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; @@ -10528,6 +10813,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&gendac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10544,6 +10830,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att491_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; if (info->local == S3_WINNER1000_805) @@ -10560,6 +10847,7 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att490_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10575,10 +10863,43 @@ s3_init(const device_t *info) svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&att492_ramdac_device); + s3->ramdac_type = ATT49X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; + case S3_ELSAWIN1K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + + case S3_ELSAWIN2K_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0x91; /*86C928D*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = 0; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; + svga->clock_gen = device_add(&ics9161_device); + svga->getclock = ics9161_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_METHEUS_86C928: svga->decode_mask = (4 << 20) - 1; stepping = 0x91; /*86C928D*/ @@ -10588,10 +10909,27 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&ics2494an_305_device); svga->getclock = ics2494_getclock; break; + case S3_ELSAWIN1KPCI_86C928: + svga->decode_mask = (4 << 20) - 1; + stepping = 0xb0; /*86C928PCI*/ + s3->id = stepping; + s3->id_ext = stepping; + s3->id_ext_pci = stepping; + s3->packed_mmio = 0; + svga->crtc[0x5a] = 0x0a; + svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; + svga->clock_gen = device_add(&icd2061_device); + svga->getclock = icd2061_getclock; + s3->elsa_eeprom = 1; + icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + break; + case S3_SPEA_MERCURY_LITE_PCI: svga->decode_mask = (4 << 20) - 1; stepping = 0xb0; /*86C928PCI*/ @@ -10601,6 +10939,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sc1502x_ramdac_device); + s3->ramdac_type = SC1502X; svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; break; @@ -10619,6 +10958,7 @@ s3_init(const device_t *info) s3->packed_mmio = 0; svga->crtc[0x5a] = 0x0a; svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; break; @@ -10636,6 +10976,7 @@ s3_init(const device_t *info) switch (info->local) { case S3_ELSAWIN2KPROX_964: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; s3->elsa_eeprom = 1; @@ -10643,8 +10984,10 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&bt485_ramdac_device); + s3->ramdac_type = BT48X; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); break; } break; @@ -10678,6 +11021,7 @@ s3_init(const device_t *info) case S3_PHOENIX_VISION968: case S3_NUMBER9_9FX_771: svga->ramdac = device_add(&ibm_rgb528_ramdac_device); + s3->ramdac_type = IBM_RGB; svga->clock_gen = svga->ramdac; svga->getclock = ibm_rgb528_getclock; if (info->local == S3_ELSAWIN2KPROX) { @@ -10690,6 +11034,7 @@ s3_init(const device_t *info) break; default: svga->ramdac = device_add(&tvp3026_ramdac_device); + s3->ramdac_type = TVP3026; svga->clock_gen = svga->ramdac; svga->getclock = tvp3026_getclock; svga->conv_16to32 = tvp3026_conv_16to32; @@ -10718,10 +11063,13 @@ s3_init(const device_t *info) if (info->local == S3_NUMBER9_9FX_531) { svga->ramdac = device_add(&att498_ramdac_device); + s3->ramdac_type = ATT498; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; + icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); } else { svga->ramdac = device_add(&sdac_ramdac_device); + s3->ramdac_type = S3_SDAC; svga->clock_gen = svga->ramdac; svga->getclock = sdac_getclock; } @@ -10808,6 +11156,24 @@ s3_init(const device_t *info) s3->eeprom_data[0x08] = 0x83d6; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_805_%d.nvr", s3->eeprom_inst); break; + case S3_ELSAWIN1K_86C928: + s3->eeprom_data[0x02] = 0x0912; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_vlb_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN1KPCI_86C928: + s3->eeprom_data[0x02] = 0x0914; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_928_pci_%d.nvr", s3->eeprom_inst); + break; + case S3_ELSAWIN2K_86C928: + s3->eeprom_data[0x02] = 0x0920; + s3->eeprom_data[0x07] = 0xa604; + s3->eeprom_data[0x08] = 0xa604; + snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_928_isa_%d.nvr", s3->eeprom_inst); + break; case S3_ELSAWIN2KPROX: s3->eeprom_data[0x02] = 0x094a; s3->eeprom_data[0x07] = 0xf424; @@ -10910,6 +11276,24 @@ s3_mirocrystal_10sd_805_available(void) return rom_present(ROM_MIROCRYSTAL10SD_805); } +static int +s3_elsa_winner1000_86c928_vlb_available(void) +{ + return rom_present(ROM_ELSAWIN1KVL_86C928); +} + +static int +s3_elsa_winner1000_86c928_pci_available(void) +{ + return rom_present(ROM_ELSAWIN1KPCI_86C928); +} + +static int +s3_elsa_winner2000_86c928_available(void) +{ + return rom_present(ROM_ELSAWIN2K_86C928); +} + static int s3_metheus_86c928_available(void) { @@ -11350,7 +11734,7 @@ const device_t s3_spea_mirage_86c801_isa_device = { }; const device_t s3_winner1000_805_isa_device = { - .name = "S3 86c805 ISA (ELSA Winner 1000)", + .name = "S3 86c805 ISA (ELSA Winner 1000 805i)", .internal_name = "winner1000_805_isa", .flags = DEVICE_ISA16, .local = S3_WINNER1000_805, @@ -11447,6 +11831,34 @@ const device_t s3_phoenix_86c805_vlb_device = { .config = s3_9fx_config }; +const device_t s3_elsa_winner1000_86c928_vlb_device = { + .name = "S3 86c928 VLB (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_vlb", + .flags = DEVICE_VLB, + .local = S3_ELSAWIN1K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_vlb_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + +const device_t s3_elsa_winner2000_86c928_isa_device = { + .name = "S3 86c928 ISA (ELSA Winner 2000 928)", + .internal_name = "elsawin2k928_isa", + .flags = DEVICE_ISA16, + .local = S3_ELSAWIN2K_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner2000_86c928_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + const device_t s3_metheus_86c928_isa_device = { .name = "S3 86c928 ISA (Metheus Premier 928)", .internal_name = "metheus928_isa", @@ -11475,6 +11887,21 @@ const device_t s3_metheus_86c928_vlb_device = { .config = s3_standard_config }; +const device_t s3_elsa_winner1000_86c928_pci_device = { + .name = "S3 86c928 PCI (ELSA Winner 1000 928)", + .internal_name = "elsawin1k928_pci", + .flags = DEVICE_PCI, + .local = S3_ELSAWIN1KPCI_86C928, + .init = s3_init, + .close = s3_close, + .reset = s3_reset, + .available = s3_elsa_winner1000_86c928_pci_available, + .speed_changed = s3_speed_changed, + .force_redraw = s3_force_redraw, + .config = s3_standard_config +}; + + const device_t s3_spea_mercury_lite_86c928_pci_device = { .name = "S3 86c928 PCI (SPEA Mercury Lite)", .internal_name = "spea_mercurylite_pci", diff --git a/src/video/vid_table.c b/src/video/vid_table.c index c99f4aad1..20a8f311d 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -91,7 +91,6 @@ video_cards[] = { { .device = &nga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &nec_sv9000_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &ogc_device, .flags = VIDEO_FLAG_TYPE_NONE }, - { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti037c_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti067_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &oti077_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -127,10 +126,12 @@ video_cards[] = { { .device = &gd5434_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_diamond_speedstar_64_a3_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &inmos_isa_device, .flags = VIDEO_FLAG_TYPE_XGA }, + { .device = &jvga_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &radius_svga_multiview_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth_vram_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_orchid_86c911_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_ami_86c924_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner2000_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_phoenix_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mirage_86c801_isa_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -160,6 +161,7 @@ video_cards[] = { { .device = &gd5430_diamond_speedstar_pro_se_a8_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5430_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &gd5434_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_metheus_86c928_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_8s_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_mirocrystal_10sd_805_vlb_device, .flags = VIDEO_FLAG_TYPE_NONE }, @@ -199,6 +201,7 @@ video_cards[] = { { .device = &et4000w32p_cardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_noncardex_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &et4000w32p_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, + { .device = &s3_elsa_winner1000_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_spea_mercury_lite_86c928_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_diamond_stealth64_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, { .device = &s3_elsa_winner2000_pro_x_964_pci_device, .flags = VIDEO_FLAG_TYPE_NONE }, From d46e2bc8c67d86ab28713b21b8ea2caade5ce15d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Sep 2025 01:12:30 +0200 Subject: [PATCH 025/138] Apply the dynamic SCSI buffer window sizing fix to MO, removable disk, and CD-ROM as well. --- src/disk/mo.c | 11 ++++++++++- src/disk/rdisk.c | 11 ++++++++++- src/include/86box/mo.h | 1 + src/include/86box/rdisk.h | 1 + src/include/86box/scsi_cdrom.h | 1 + src/scsi/scsi_cdrom.c | 15 +++++++++++---- src/scsi/scsi_disk.c | 2 ++ 7 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/disk/mo.c b/src/disk/mo.c index b287f68a0..5ffe74f78 100644 --- a/src/disk/mo.c +++ b/src/disk/mo.c @@ -664,8 +664,17 @@ static void mo_buf_alloc(mo_t *dev, uint32_t len) { mo_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->buffer == NULL) + + if (dev->buffer == NULL) { dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/disk/rdisk.c b/src/disk/rdisk.c index b51dc4e66..683b1e963 100644 --- a/src/disk/rdisk.c +++ b/src/disk/rdisk.c @@ -747,8 +747,17 @@ static void rdisk_buf_alloc(rdisk_t *dev, const uint32_t len) { rdisk_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->buffer == NULL) + + if (dev->buffer == NULL) { dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/include/86box/mo.h b/src/include/86box/mo.h index 6d308adb8..76e7cbdbe 100644 --- a/src/include/86box/mo.h +++ b/src/include/86box/mo.h @@ -140,6 +140,7 @@ typedef struct mo_t { void * log; uint8_t *buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/rdisk.h b/src/include/86box/rdisk.h index df48ba703..c226a2c9d 100644 --- a/src/include/86box/rdisk.h +++ b/src/include/86box/rdisk.h @@ -117,6 +117,7 @@ typedef struct rdisk_t { void *log; uint8_t *buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/scsi_cdrom.h b/src/include/86box/scsi_cdrom.h index c01f347a8..005223e27 100644 --- a/src/include/86box/scsi_cdrom.h +++ b/src/include/86box/scsi_cdrom.h @@ -36,6 +36,7 @@ typedef struct scsi_cdrom_t { void * log; uint8_t * buffer; + size_t buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index be23a66fe..309886357 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -857,11 +857,18 @@ scsi_cdrom_unit_attention(scsi_cdrom_t *dev) static void scsi_cdrom_buf_alloc(scsi_cdrom_t *dev, const uint32_t len) { - if (dev->buffer == NULL) - dev->buffer = (uint8_t *) malloc(len); + scsi_cdrom_log(dev->log, "Allocated buffer length: %i\n", len); - scsi_cdrom_log(dev->log, "Allocated buffer length: %i, buffer = %p\n", - len, dev->buffer); + if (dev->buffer == NULL) { + dev->buffer = (uint8_t *) malloc(len); + dev->buffer_sz = len; + } + + if (len > dev->buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->buffer, len); + dev->buffer = buf; + dev->buffer_sz = len; + } } static void diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index bfa8b42cf..9c8d36f7f 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -623,10 +623,12 @@ static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); + if (dev->temp_buffer == NULL) { dev->temp_buffer = (uint8_t *) malloc(len); dev->temp_buffer_sz = len; } + if (len > dev->temp_buffer_sz) { uint8_t *buf = (uint8_t *) realloc(dev->temp_buffer, len); dev->temp_buffer = buf; From 433c45b3e6b0a02d0453497aaba65b569de78497 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 6 Sep 2025 18:24:29 -0500 Subject: [PATCH 026/138] Give the Intel TC430HX and Sony Vaio PCV-90 their onboard YMF701 audio --- src/machine/m_at_socket7.c | 9 +++++++++ src/machine/machine_table.c | 8 ++++---- src/sound/snd_ymf701.c | 3 ++- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index b0651a8af..994f2151e 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -316,6 +316,9 @@ machine_at_tc430hx_gpio_init(void) else if (cpu_busspeed > 60000000) gpio |= 0xffff00ff; + if (sound_card_current[0] == SOUND_INTERNAL) + gpio |= 0xffff04ff; + machine_set_gpio_default(gpio); } @@ -350,6 +353,9 @@ machine_at_tc430hx_init(const machine_t *model) if (gfxcard[0] == VID_INTERNAL) device_add(machine_get_vid_device(machine)); + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + device_add(&i430hx_device); device_add(&piix3_device); device_add_params(&pc87306_device, (void *) PCX730X_AMI); @@ -452,6 +458,9 @@ machine_at_pcv90_init(const machine_t *model) device_add_params(&pc87306_device, (void *) PCX730X_AMI); device_add(&intel_flash_bxt_ami_device); + if (sound_card_current[0] == SOUND_INTERNAL) + machine_snd = device_add(machine_get_snd_device(machine)); + return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7891bb3db..6a5ec2028 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -13854,7 +13854,7 @@ const machine_t machines[] = { .max_multi = 3.5 }, .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ + .flags = MACHINE_VIDEO | MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_GAMEPORT | MACHINE_USB, /* Has internal sound: Yamaha YMF701-S */ .ram = { .min = 8192, .max = 524288, @@ -13873,7 +13873,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = &s3_virge_375_pci_device, - .snd_device = NULL, + .snd_device = &ymf701_device, .net_device = NULL }, /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix @@ -13991,7 +13991,7 @@ const machine_t machines[] = { .max_multi = 3.0 }, .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE_DUAL | MACHINE_APM, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_SOUND | MACHINE_GAMEPORT, /* Machine has internal video: ATI Mach64GT-B 3D Rage II */ .ram = { .min = 8192, .max = 524288, @@ -14010,7 +14010,7 @@ const machine_t machines[] = { .fdc_device = NULL, .sio_device = NULL, .vid_device = NULL, - .snd_device = NULL, + .snd_device = &ymf701_device, .net_device = NULL }, /* [TEST] The board doesn't seem to have a KBC at all, which probably means it's an on-chip one on the PC87306 SIO. diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index 430bfec4c..1e45c786a 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -286,7 +286,8 @@ ymf701_reg_write(uint16_t addr, uint8_t val, void *priv) sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_irq); sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_dma); ymf701_add_opl(ymf701); - io_sethandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + if (ymf701->cur_addr != 0x00) + io_sethandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); break; case 0x03: /* MPU/OPL/Gameport Config */ ymf701->regs[0x03] = val; From 569827ce02f92808b2d8a173fbfbf9ce42acf623 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 7 Sep 2025 14:18:51 +0600 Subject: [PATCH 027/138] MGA: Implement unscaled YUV blits for ILOAD --- src/video/vid_mga.c | 117 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 7fdc04e9e..564136428 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -3598,6 +3598,12 @@ dither_24_to_8(int r, int g, int b) return ((b >> 6) & 3) | (((g >> 5) & 7) << 2) | (((r >> 5) & 7) << 5); } +#define CLAMP(x) \ + do { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } while (0) + static void blit_iload_iload(mystique_t *mystique, uint32_t data, int size) { @@ -3613,7 +3619,50 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) const int trans_sel = (mystique->dwgreg.dwgctrl_running & DWGCTRL_TRANS_MASK) >> DWGCTRL_TRANS_SHIFT; uint8_t const *const trans = &trans_masks[trans_sel][(mystique->dwgreg.selline & 3) * 4]; uint32_t data_mask = 1; + /* YUV stuff */ + int y0; + int y1; + int u; + int v; + int dR; + int dG; + int dB; + int r0; + int g0; + int b0; + int r1; + int g1; + int b1; + switch (mystique->dwgreg.dwgctrl_running & DWGCTRL_BLTMOD_MASK) { + case DWGCTRL_BLTMOD_BUYUV: + y0 = (298 * ((int) (data & 0xff) - 16)) >> 8; + u = ((data >> 8) & 0xff) - 0x80; + y1 = (298 * ((int) ((data >> 16) & 0xff) - 16)) >> 8; + v = ((data >> 24) & 0xff) - 0x80; + dR = (309 * v) >> 8; + dG = (100 * u + 208 * v) >> 8; + dB = (516 * u) >> 8; + + r0 = y0 + dR; + CLAMP(r0); + g0 = y0 - dG; + CLAMP(g0); + b0 = y0 + dB; + CLAMP(b0); + r1 = y1 + dR; + CLAMP(r1); + g1 = y1 - dG; + CLAMP(g1); + b1 = y1 + dB; + CLAMP(b1); + + data64 = b0 | (g0 << 8) | (r0 << 16); + data64 |= ((uint64_t) b1 << 32) | ((uint64_t) g1 << 40) | ((uint64_t) r1 << 48); + size = 64; + + break; + } switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { case MACCESS_PWIDTH_8: bltckey &= 0xff; @@ -3947,6 +3996,65 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) mystique->dwgreg.iload_rem_data = data64; break; + case DWGCTRL_BLTMOD_BUYUV: + while (size >= 32) { + int draw = (!transc || (data & bltcmsk) != bltckey) && trans[mystique->dwgreg.xdst & 3]; + if (mystique->dwgreg.xdst >= mystique->dwgreg.cxleft && mystique->dwgreg.xdst <= mystique->dwgreg.cxright && mystique->dwgreg.ydst_lin >= mystique->dwgreg.ytop && mystique->dwgreg.ydst_lin <= mystique->dwgreg.ybot && draw) { + switch (mystique->maccess_running & MACCESS_PWIDTH_MASK) { + case MACCESS_PWIDTH_16: + { + dst = ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w]; + + dst = bitop(dither(mystique, (data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF, mystique->dwgreg.xdst & 1, mystique->dwgreg.selline & 1), dst, mystique->dwgreg.dwgctrl_running); + + ((uint16_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_w) >> 11] = changeframecount; + break; + } + case MACCESS_PWIDTH_8: + { + dst = ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask]; + + dst = bitop(dither_24_to_8((data64 >> 16) & 0xFF, (data64 >> 8) & 0xFF, data64 & 0xFF), dst, mystique->dwgreg.dwgctrl_running); + + ((uint8_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask) >> 12] = changeframecount; + break; + } + default: { + dst = ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l]; + + dst = bitop(data, dst, mystique->dwgreg.dwgctrl_running); + ((uint32_t *) svga->vram)[(mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l] = dst; + svga->changedvram[((mystique->dwgreg.ydst_lin + mystique->dwgreg.xdst) & mystique->vram_mask_l) >> 10] = changeframecount; + break; + } + } + } + + size -= 32; + data64 >>= 32ULL; + + if (mystique->dwgreg.xdst == mystique->dwgreg.fxright) { + mystique->dwgreg.xdst = mystique->dwgreg.fxleft; + mystique->dwgreg.ydst_lin += (mystique->dwgreg.pitch & PITCH_MASK); + mystique->dwgreg.selline = (mystique->dwgreg.selline + 1) & 7; + mystique->dwgreg.length_cur--; + if (!mystique->dwgreg.length_cur) { + mystique->busy = 0; + mystique->blitter_complete_refcount++; + break; + } + data64 = 0; + size = 0; + break; + } else + mystique->dwgreg.xdst = (mystique->dwgreg.xdst + 1) & 0xffff; + } + mystique->dwgreg.iload_rem_count = size; + mystique->dwgreg.iload_rem_data = data64; + break; + case DWGCTRL_BLTMOD_BU32BGR: size += mystique->dwgreg.iload_rem_count; while (size >= 32) { @@ -3996,12 +4104,6 @@ blit_iload_iload(mystique_t *mystique, uint32_t data, int size) } } -#define CLAMP(x) \ - do { \ - if ((x) & ~0xff) \ - x = ((x) < 0) ? 0 : 0xff; \ - } while (0) - static void blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) { @@ -4053,7 +4155,7 @@ blit_iload_iload_scale(mystique_t *mystique, uint32_t data, int size) break; case MACCESS_PWIDTH_32: data64 = b0 | (g0 << 8) | (r0 << 16); - data64 |= ((uint64_t) b0 << 32) | ((uint64_t) g0 << 40) | ((uint64_t) r0 << 48); + data64 |= ((uint64_t) b1 << 32) | ((uint64_t) g1 << 40) | ((uint64_t) r1 << 48); size = 64; break; @@ -5925,6 +6027,7 @@ blit_iload(mystique_t *mystique) case DWGCTRL_BLTMOD_BMONOWF: case DWGCTRL_BLTMOD_BU24RGB: case DWGCTRL_BLTMOD_BU32RGB: + case DWGCTRL_BLTMOD_BUYUV: mystique->dwgreg.length_cur = mystique->dwgreg.length; mystique->dwgreg.xdst = mystique->dwgreg.fxleft; mystique->dwgreg.iload_rem_data = 0; From b74c513273f2a5264faf621422ce85bcbbe0a4aa Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 7 Sep 2025 18:01:37 +0600 Subject: [PATCH 028/138] Adjust `scsi_common_t` structure definition to match the rest (#6133) Fixes https://github.com/86Box/86Box/issues/6131 --- src/include/86box/scsi_device.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/scsi_device.h b/src/include/86box/scsi_device.h index 289201b04..d5d620670 100644 --- a/src/include/86box/scsi_device.h +++ b/src/include/86box/scsi_device.h @@ -388,6 +388,7 @@ typedef struct scsi_common_s { void * log; uint8_t * temp_buffer; + size_t temp_buffer_sz; /* This is atapi_cdb in ATAPI-supporting devices, and pad in SCSI-only devices. From a13bc2d532ef8af8e61b708633b081b075121313 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 Sep 2025 23:31:07 +0200 Subject: [PATCH 029/138] EGA: Remove an excess logging line. --- src/video/vid_ega.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index e96bd827c..d25861681 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -149,7 +149,6 @@ ega_out(uint16_t addr, uint8_t val, void *priv) ega->vres = !(val & 0x80); ega->pallook = ega->vres ? pallook16 : pallook64; ega->vidclock = val & 4; - pclog("clock = %01X\n", (val & 0x0c) >> 2); ega->miscout = val; ega->overscan_color = ega->vres ? pallook16[ega->attrregs[0x11] & 0x0f] : pallook64[ega->attrregs[0x11] & 0x3f]; From f3b18ef8bf242ebb63f804f588a1b5e1b774324b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 7 Sep 2025 23:38:36 +0200 Subject: [PATCH 030/138] Restore the obsolete pause resume alt opcode. As a redirect to the SCSI Pause/Resume 0x4B command. --- src/scsi/scsi_cdrom.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 309886357..f5b81e369 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -472,7 +472,7 @@ scsi_cdrom_mode_sense_read(const scsi_cdrom_t *dev, const uint8_t pgctl, default: break; - } + } return ret; } @@ -1579,7 +1579,7 @@ scsi_cdrom_read(scsi_common_t *sc) dev->drv->seek_diff = 0; if (ret > 0) { - if (osl > 0) + if (osl > 0) scsi_cdrom_set_period(dev); ui_sb_update_icon(SB_CDROM | dev->id, @@ -2626,7 +2626,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) dev->sector_type, 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (6): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2639,7 +2639,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) (cdb[9] & 0xc0) : 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (10): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2655,7 +2655,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) (cdb[9] & 0xc0) : 0x00)) { scsi_cdrom_illegal_mode(dev); ret = 0; - } + } scsi_cdrom_log(dev->log, "READ (12): Length: %i, LBA: %i\n", dev->sector_len, dev->sector_pos); break; @@ -2706,7 +2706,7 @@ scsi_cdrom_command(scsi_common_t *sc, const uint8_t *cdb) scsi_cdrom_buf_alloc(dev, dev->packet_len); dev->drv->seek_diff = ABS((int) (pos - dev->sector_pos)); - dev->drv->seek_pos = dev->sector_pos; + dev->drv->seek_pos = dev->sector_pos; /* Any of these commands stop the audio playing. */ cdrom_stop(dev->drv); @@ -3524,6 +3524,7 @@ atapi_out: break; case GPCMD_PAUSE_RESUME: + case GPCMD_PAUSE_RESUME_ALT: scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); cdrom_audio_pause_resume(dev->drv, cdb[8] & 0x01); scsi_cdrom_command_complete(dev); From 63a78e388b270ed5e24f55ca347110bfb210606a Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Sep 2025 01:38:46 +0200 Subject: [PATCH 031/138] Olivetti M19: Use the 3.71 BIOS instead, because it's newer. --- src/machine/m_xt_olivetti.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 079cd4555..13d98e6f9 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -2426,7 +2426,7 @@ machine_xt_m19_init(const machine_t *model) { int ret; - ret = bios_load_linear("roms/machines/m19/BIOS.BIN", + ret = bios_load_linear("roms/machines/m19/Olivetti M19 Resident Diagnostics Rev 3.71.BIN", 0x000fc000, 16384, 0); ret &= rom_present("roms/machines/m19/MBM2764-30 8514 107 AB PCF3.BIN"); From 845d1ddc4388b67a94497484ca5d9bb392b0b9ac Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Mon, 8 Sep 2025 11:23:08 +0700 Subject: [PATCH 032/138] Added two baud rates (28.8k and 33.6k) According to Windows 98 modem setup. --- src/network/net_modem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/net_modem.c b/src/network/net_modem.c index af97a16db..24869349f 100644 --- a/src/network/net_modem.c +++ b/src/network/net_modem.c @@ -1566,6 +1566,8 @@ static const device_config_t modem_config[] = { { .description = "57600", .value = 57600 }, { .description = "56000", .value = 56000 }, { .description = "38400", .value = 38400 }, + { .description = "33600", .value = 33600 }, + { .description = "28800", .value = 28800 }, { .description = "19200", .value = 19200 }, { .description = "14400", .value = 14400 }, { .description = "9600", .value = 9600 }, From 22ba8b32c138ea9a4931522b7f83d5ad778ac8b5 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 8 Sep 2025 15:37:11 +0600 Subject: [PATCH 033/138] Add support for Trio3D/2X's 8-bit palette DAC --- src/video/vid_s3_virge.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 3bd6d694d..d8356df4a 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -828,6 +828,9 @@ s3_virge_recalctimings(svga_t *svga) svga->hdisp = svga->hdisp_old; + if (virge->chip >= S3_TRIO3D2X) { + svga_set_ramdac_type(svga, (svga->seqregs[0x1b] & 0x10) ? RAMDAC_8BIT : RAMDAC_6BIT); + } if (!svga->scrblank && svga->attr_palette_enable && (svga->crtc[0x43] & 0x80)) { /* TODO: In case of bug reports, disable 9-dots-wide character clocks in graphics modes. */ svga->dots_per_clock = ((svga->seqregs[1] & 1) ? 16 : 18); From 84d96271dee2de8c83284181819d34fb64961c6b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Sep 2025 22:27:39 +0200 Subject: [PATCH 034/138] Implement the Super MegaZeux text mode. --- src/video/vid_svga_render.c | 70 +++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index f43db41c4..9afae254d 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -243,6 +243,8 @@ svga_render_text_80(svga_t *svga) p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; + uint32_t col = 0x00000000; + for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) addr = svga->remap_func(svga, svga->memaddr) & svga->vram_display_mask; @@ -263,30 +265,70 @@ svga_render_text_80(svga_t *svga) charaddr = svga->charseta + (chr * 128); if (drawcursor) { - bg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; - fg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; + bg = attr & 15; + fg = attr >> 4; } else { - fg = svga->pallook[svga->egapal[attr & 15] & svga->dac_mask]; - bg = svga->pallook[svga->egapal[attr >> 4] & svga->dac_mask]; + fg = attr & 15; + bg = attr >> 4; if (attr & 0x80 && svga->attrregs[0x10] & 8) { - bg = svga->pallook[svga->egapal[(attr >> 4) & 7] & svga->dac_mask]; + bg = (attr >> 4) & 7; if (svga->blink & 16) fg = bg; } } dat = svga->vram[charaddr + (svga->scanline << 2)]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + + if (svga->attrregs[0x10] & 0x40) { + pclog("256-color text mode\n"); + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) { + uint32_t col16 = (dat & (0x80 >> xx)) ? fg : bg; + if ((x + xx - svga->scrollcache) & 1) { + col |= col16; + if ((x + xx - 1) >= 0) + p[xx - 1] = svga->pallook[col & svga->dac_mask]; + if ((x + xx) >= 0) + p[xx] = svga->pallook[col & svga->dac_mask]; + } else + col = col16 << 4; + } + } else { + for (xx = 0; xx < 9; xx++) { + uint32_t col16; + if (xx < 8) + col16 = (dat & (0x80 >> xx)) ? fg : bg; + else if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + col16 = bg; + else + col16 = (dat & 1) ? fg : bg; + if ((x + xx - svga->scrollcache) & 1) { + col |= col16; + if ((x + xx - 1) >= 0) + p[xx - 1] = svga->pallook[col & svga->dac_mask]; + if ((x + xx) >= 0) + p[xx] = svga->pallook[col & svga->dac_mask]; + } else + col = col16 << 4; + } + } } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; - else - p[8] = (dat & 1) ? fg : bg; + fg = svga->pallook[svga->egapal[fg] & svga->dac_mask]; + bg = svga->pallook[svga->egapal[bg] & svga->dac_mask]; + + if (svga->seqregs[1] & 1) { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + } else { + for (xx = 0; xx < 8; xx++) + p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) + p[8] = bg; + else + p[8] = (dat & 1) ? fg : bg; + } } + svga->memaddr += 4; p += xinc; } From 8bb6444c7a66043e6176f6be0121f71d0e877bb4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 8 Sep 2025 22:59:34 +0200 Subject: [PATCH 035/138] Latest video fixes of the day (September 8th, 2025) On soft-reset, reset the Misc Multifunc (0x0D/0x0E) values to sane defaults per manuals. --- src/video/vid_s3.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 870221742..5b9626ad9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -5025,12 +5025,13 @@ s3_updatemapping(s3_t *s3) if (s3->chip >= S3_86C928) { s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); - if (s3->chip >= S3_86C928 && s3->chip <= S3_86C805) { + if (s3->chip <= S3_86C805) { if (s3->vlb) s3->linear_base &= 0x03ffffff; else if (!s3->pci) s3->linear_base &= 0x00ffffff; } + if ((svga->crtc[0x58] & 0x10) || (s3->accel.advfunc_cntl & 0x10)) { /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); @@ -10263,8 +10264,10 @@ s3_reset(void *priv) s3_t *s3 = (s3_t *) priv; if (reset_state != NULL) { - s3->accel.multifunc[0xe] &= ~(0x200 | 0x10); s3_disable_handlers(s3); + s3->accel.multifunc[0xd] = 0xd000; + s3->accel.multifunc[0xe] = 0xe000; + s3_log("S3 reset done.\n"); s3->force_busy = 0; s3->blitter_busy = 0; s3->fifo_read_idx = 0; @@ -10273,7 +10276,8 @@ s3_reset(void *priv) reset_state->pci_slot = s3->pci_slot; *s3 = *reset_state; - } + } else + s3_log("NULL reset.\n"); } static uint16_t From 3a703d0c0d1f8c2c23846b92849eb8eef9826466 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Sep 2025 00:18:14 +0200 Subject: [PATCH 036/138] Last minute changes for the high color S3 911/924 mode Read mask initialized to 0xff allows proper colors on initial boot of Windows. --- src/video/vid_s3.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 5b9626ad9..53f75365f 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -830,6 +830,7 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) { svga_t *svga = &s3->svga; + s3_log("OUTB FIFO=%04x, val=%02x.\n", port, val); switch (port) { case 0x8148: case 0x82e8: @@ -8807,6 +8808,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + s3_log("CMD2: RDMASK16CHECK=%d, rdmask=%04x.\n", s3->accel.rd_mask_16bit_check, rd_mask); if (s3->accel.rd_mask_16bit_check) { if (s3->accel.cmd == 0x41b3) { if (frgd_mix == 0) { @@ -9211,6 +9213,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if ((s3->bpp == 0) && s3->color_16bit) { s3->accel.rd_mask_16bit_check = ((rd_mask & 0xff00) != 0xff00) && rd_mask; + s3_log("CMD6: RDMASK16CHECK=%d.\n", s3->accel.rd_mask_16bit_check); if (s3->accel.rd_mask_16bit_check) { if (!(clip_r & 0x400)) s3->accel.start = 1; @@ -10778,6 +10781,7 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; + s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); s3->ramdac_type = SC1148X; @@ -10799,6 +10803,7 @@ s3_init(const device_t *info) s3->id_ext = stepping; s3->id_ext_pci = 0; s3->packed_mmio = 0; + s3->accel.rd_mask = 0xff; svga->ramdac = device_add(&sc11483_ramdac_device); s3->ramdac_type = SC1148X; From 91d7bb38390cb8458ed906bd4cc112543089e329 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Sep 2025 01:29:47 +0200 Subject: [PATCH 037/138] (S)VGA render: remove an excess logging line. --- src/video/vid_svga_render.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 9afae254d..5e4844aed 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -280,7 +280,6 @@ svga_render_text_80(svga_t *svga) dat = svga->vram[charaddr + (svga->scanline << 2)]; if (svga->attrregs[0x10] & 0x40) { - pclog("256-color text mode\n"); if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) { uint32_t col16 = (dat & (0x80 >> xx)) ? fg : bg; From 430627e77669e82724bce66991872640db660a20 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 10:11:48 +0800 Subject: [PATCH 038/138] fix file handler typo in line #422 --- src/minitrace/minitrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/minitrace/minitrace.c b/src/minitrace/minitrace.c index 290486ec5..9762f1c55 100644 --- a/src/minitrace/minitrace.c +++ b/src/minitrace/minitrace.c @@ -419,7 +419,7 @@ void mtr_flush_with_state(int is_last) { len = snprintf(linebuf, ARRAY_SIZE(linebuf), "%s{\"cat\":\"%s\",\"pid\":%i,\"tid\":%i,\"ts\":%" PRId64 ",\"ph\":\"%c\",\"name\":\"%s\",\"args\":{%s}%s}", first_line ? "" : ",\n", cat, raw->pid, raw->tid, raw->ts - time_offset, raw->ph, raw->name, arg_buf, id_buf); - fwrite(linebuf, 1, len, f); + fwrite(linebuf, 1, len, fp); first_line = 0; if (raw->arg_type == MTR_ARG_TYPE_STRING_COPY) { From fb64862fcffc994d1e4666c773a6ee06f74b10a5 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 12:33:52 +0800 Subject: [PATCH 039/138] rename machine 'Multitech PC-500' to 'Multitech PC-500 plus' --- src/include/86box/machine.h | 2 +- src/machine/m_xt.c | 4 ++-- src/machine/machine_table.c | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 7ab675a6c..6eecb9f49 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1319,7 +1319,7 @@ extern const device_t jukopc_device; extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_kaypropc_init(const machine_t *); extern int machine_xt_micoms_xl7turbo_init(const machine_t *); -extern int machine_xt_pc500_init(const machine_t *); +extern int machine_xt_pc500plus_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc4i_init(const machine_t *); extern int machine_xt_openxt_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 954483d62..b909857d1 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -975,12 +975,12 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) } int -machine_xt_pc500_init(const machine_t *model) +machine_xt_pc500plus_init(const machine_t *model) { int ret; ret = bios_load_linear("roms/machines/pc500/rom404.bin", - 0x000f8000, 32768, 0); + 0x000fc000, 16384, 0); if (bios_only || !ret) return ret; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7891bb3db..ec5f2e9f0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1095,11 +1095,11 @@ const machine_t machines[] = { .net_device = NULL }, { - .name = "[8088] Multitech PC-500", - .internal_name = "pc500", + .name = "[8088] Multitech PC-500 plus", + .internal_name = "pc500plus", .type = MACHINE_TYPE_8088, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_xt_pc500_init, + .init = machine_xt_pc500plus_init, .p1_handler = NULL, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From a5a9ca148e2ef48da7884daf11abbd39fe64afab Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 12:39:41 +0800 Subject: [PATCH 040/138] add machine Multitech PC-500 with BIOS ROM v3.10 and v3.30 --- src/include/86box/machine.h | 4 ++ src/machine/m_xt.c | 75 +++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 43 +++++++++++++++++++++ 3 files changed, 122 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6eecb9f49..b2520976e 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1319,6 +1319,10 @@ extern const device_t jukopc_device; extern int machine_xt_jukopc_init(const machine_t *); extern int machine_xt_kaypropc_init(const machine_t *); extern int machine_xt_micoms_xl7turbo_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t pc500_device; +#endif +extern int machine_xt_pc500_init(const machine_t *); extern int machine_xt_pc500plus_init(const machine_t *); extern int machine_xt_pc700_init(const machine_t *); extern int machine_xt_pc4i_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index b909857d1..815045389 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -974,6 +974,81 @@ machine_xt_micoms_xl7turbo_init(const machine_t *model) return ret; } +static const device_config_t pc500_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "pc500_330", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .bios = { + { + .name = "3.30", + .internal_name = "pc500_330", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc500/rom330.bin", "" } + }, + { + .name = "3.10", + .internal_name = "pc500_310", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/pc500/rom310.bin", "" } + }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t pc500_device = { + .name = "Multitech PC-500", + .internal_name = "pc500_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = pc500_config +}; + +int +machine_xt_pc500_init(const machine_t *model) +{ + int ret = 0; + const char *fn; + + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 8192, 0); + device_context_restore(); + + if (bios_only || !ret) + return ret; + + device_add(&kbc_pc_device); + + machine_xt_common_init(model, 0); + + return ret; +} + int machine_xt_pc500plus_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index ec5f2e9f0..8f6d20a27 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1094,6 +1094,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8088] Multitech PC-500", + .internal_name = "pc500", + .type = MACHINE_TYPE_8088, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_xt_pc500_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8088, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 128, + .max = 640, + .step = 64 + }, + .nvrmask = 0, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_pc_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pc500_device, + .kbd_device = &keyboard_pc_xt_device, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8088] Multitech PC-500 plus", .internal_name = "pc500plus", From 32555f0edb61b434acaf9cd890bc6ae227ed9cf6 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Tue, 9 Sep 2025 13:03:18 +0800 Subject: [PATCH 041/138] add machine 'Multitech PC-900' --- src/include/86box/machine.h | 1 + src/machine/m_at_286.c | 21 ++++++++++++++++++ src/machine/machine_table.c | 44 +++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b2520976e..6de1586dc 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -498,6 +498,7 @@ extern int machine_at_cmdpc_init(const machine_t *); extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_grid1520_init(const machine_t *); +extern int machine_at_mpfpc900_init(const machine_t *); extern int machine_at_mr286_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_m290_init(const machine_t *); diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index f74ad5115..a1b71a817 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -328,6 +328,27 @@ machine_at_grid1520_init(const machine_t *model) { return ret; } +int +machine_at_mpfpc900_init(const machine_t *model) { + int ret = 0; + + ret = bios_load_linear("roms/machines/pc900/mpf_pc900_v207a.bin", + 0x000f8000, 32768, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + + mem_remap_top(384); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + return ret; +} + int machine_at_mr286_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 8f6d20a27..20baadfcf 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3343,6 +3343,50 @@ const machine_t machines[] = { .net_device = NULL }, /* Has IBM AT KBC firmware. */ + { + .name = "[ISA] Multitech PC-900", + .internal_name = "mpfpc900", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_mpfpc900_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 6000000, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 1024, + .step = 128 + }, + .nvrmask = 63, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ { .name = "[ISA] MR BIOS 286 clone", .internal_name = "mr286", From 51c23289499b4dbc8b707f45dd7670862796144b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Sep 2025 20:11:59 +0200 Subject: [PATCH 042/138] (S)VGA: Implement odd pel shifts in 256-color modes. --- src/include/86box/vid_svga.h | 1 + src/video/vid_svga.c | 9 +++++++-- src/video/vid_svga_render.c | 25 ++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index a66dd8c03..cbd6c511a 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -141,6 +141,7 @@ typedef struct svga_t { int render_line_offset; int start_retrace_latch; int vga_mode; + int half_pixel; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 302a26f23..d3a95f0bb 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1480,6 +1480,7 @@ svga_poll(void *priv) svga->scanline = 0; if (svga->attrregs[0x10] & 0x20) { svga->scrollcache = 0; + svga->half_pixel = 0; svga->x_add = svga->left_overscan; } } @@ -1580,11 +1581,15 @@ svga_poll(void *priv) if (svga->scrollcache > 8) svga->scrollcache = 0; } + svga->half_pixel = 0; } else if ((svga->render == svga_render_2bpp_lowres) || (svga->render == svga_render_2bpp_highres) || - (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) + (svga->render == svga_render_4bpp_lowres) || (svga->render == svga_render_4bpp_highres)) { + svga->half_pixel = 0; svga->scrollcache &= 0x07; - else + } else { + svga->half_pixel = svga->scrollcache & 0x01; svga->scrollcache = (svga->scrollcache & 0x06) >> 1; + } if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) svga->scrollcache <<= 1; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 5e4844aed..773874322 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -805,6 +805,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t incr_counter = 0; uint32_t load_counter = 0; uint32_t edat = 0; + uint32_t col = 0; + uint32_t col2 = 0; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) { if (load_counter == 0) { /* Find our address */ @@ -923,8 +925,19 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } } else if (combine8bits) { if (svga->packed_4bpp) { - uint32_t p0 = svga->map8[c0 & svga->dac_mask]; - uint32_t p1 = svga->map8[c1 & svga->dac_mask]; + uint32_t p0; + uint32_t p1; + if (svga->half_pixel) { + col |= (c0 >> 4) & 0xff; + col2 = (c0 << 4) & 0xff; + col2 |= (c1 >> 4) & 0xff; + p0 = svga->map8[col & svga->dac_mask]; + p1 = svga->map8[col2 & svga->dac_mask]; + col = (c1 << 4) & 0xff; + } else { + p0 = svga->map8[c0 & svga->dac_mask]; + p1 = svga->map8[c1 & svga->dac_mask]; + } const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -932,7 +945,13 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx + dotwidth] = p1; } else { uint32_t ccombined = (c0 << 4) | c1; - uint32_t p0 = svga->map8[ccombined & svga->dac_mask]; + uint32_t p0; + if (svga->half_pixel) { + col |= (ccombined >> 4) & 0xff; + p0 = svga->map8[col & svga->dac_mask]; + col = (ccombined << 4) & 0xff; + } else + p0 = svga->map8[ccombined & svga->dac_mask]; const int outoffs = (i >> 1) << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; From e630a8fa25f3b80d81776a1fa3fc2985a83e0309 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 Sep 2025 21:50:49 +0200 Subject: [PATCH 043/138] (S)VGA: Implement some level of pel shift memorization. --- src/video/vid_svga_render.c | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 773874322..92228243f 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -243,7 +243,7 @@ svga_render_text_80(svga_t *svga) p = &svga->monitor->target_buffer->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; - uint32_t col = 0x00000000; + static uint32_t col = 0x00000000; for (int x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { if (!svga->force_old_addr) @@ -312,19 +312,21 @@ svga_render_text_80(svga_t *svga) } } } else { - fg = svga->pallook[svga->egapal[fg] & svga->dac_mask]; - bg = svga->pallook[svga->egapal[bg] & svga->dac_mask]; - if (svga->seqregs[1] & 1) { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + for (xx = 0; xx < 8; xx++) { + col = (col << 4) | ((dat & (0x80 >> xx)) ? fg : bg); + p[xx] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } } else { - for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + for (xx = 0; xx < 8; xx++) { + col = (col << 4) | ((dat & (0x80 >> xx)) ? fg : bg); + p[xx] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; + } if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; + col = (col << 4) | bg; else - p[8] = (dat & 1) ? fg : bg; + col = (col << 4) | ((dat & 1) ? fg : bg); + p[8] = svga->pallook[svga->egapal[col & 0x0f] & svga->dac_mask]; } } @@ -805,8 +807,8 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t incr_counter = 0; uint32_t load_counter = 0; uint32_t edat = 0; - uint32_t col = 0; - uint32_t col2 = 0; + static uint32_t col = 0; + static uint32_t col2 = 0; for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += charwidth) { if (load_counter == 0) { /* Find our address */ @@ -928,6 +930,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t p0; uint32_t p1; if (svga->half_pixel) { + col &= 0xf0; col |= (c0 >> 4) & 0xff; col2 = (c0 << 4) & 0xff; col2 |= (c1 >> 4) & 0xff; @@ -937,6 +940,7 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) } else { p0 = svga->map8[c0 & svga->dac_mask]; p1 = svga->map8[c1 & svga->dac_mask]; + col = p1; } const int outoffs = i << dwshift; for (int subx = 0; subx < dotwidth; subx++) @@ -947,11 +951,14 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) uint32_t ccombined = (c0 << 4) | c1; uint32_t p0; if (svga->half_pixel) { + col &= 0xf0; col |= (ccombined >> 4) & 0xff; p0 = svga->map8[col & svga->dac_mask]; col = (ccombined << 4) & 0xff; - } else + } else { p0 = svga->map8[ccombined & svga->dac_mask]; + col = p0; + } const int outoffs = (i >> 1) << dwshift; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx] = p0; @@ -964,6 +971,11 @@ svga_render_indexed_gfx(svga_t *svga, bool highres, bool combine8bits) p[outoffs + subx] = p0; for (int subx = 0; subx < dotwidth; subx++) p[outoffs + subx + dotwidth] = p1; + if ((x + i - svga->scrollcache) & 0x01) + /* The lower 4 bits are undefined at this point. */ + col = c1 << 4; + else + col = (c0 << 4) | c1; } } From 3a67c54687078255abbdb1c3b5e917ca65c691fc Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Sep 2025 23:07:29 +0200 Subject: [PATCH 044/138] Overriding changes (September 9th, 2025) Dealing with 3D card overriding with XGA/IBM 8514/A compatibles again... --- src/video/vid_8514a.c | 230 +++++++++++++++++++++-------------------- src/video/vid_xga.c | 234 +++++++++++++++++++++--------------------- 2 files changed, 236 insertions(+), 228 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 32a402ec5..7b747ddc0 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -3674,143 +3674,147 @@ ibm8514_poll(void *priv) ibm8514_log("IBM 8514/A poll=%x offtime=%" PRIu64 ", ontime=%" PRIu64 ".\n", dev->on, dev->dispofftime, dev->dispontime); if (dev->on) { ibm8514_log("ON!\n"); - if (!dev->linepos) { - if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; - dev->hwcursor_oddeven = 0; - } - - if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { - dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); - dev->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, dev->dispofftime); - svga->cgastat |= 1; - dev->linepos = 1; - - if (dev->dispon) { - dev->hdisp_on = 1; - - dev->memaddr &= dev->vram_mask; - - if (dev->firstline == 2000) { - dev->firstline = dev->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + if (svga->override) + svga_set_poll(svga); + else { + if (!dev->linepos) { + if ((dev->displine == ((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y)) && dev->hwcursor_latch.ena) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - dev->hwcursor_latch.yoff; + dev->hwcursor_oddeven = 0; } - if (dev->hwcursor_on) - dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; + if ((dev->displine == (((dev->hwcursor_latch.y < 0) ? 0 : dev->hwcursor_latch.y) + 1)) && dev->hwcursor_latch.ena && dev->interlace) { + dev->hwcursor_on = dev->hwcursor_latch.cur_ysize - (dev->hwcursor_latch.yoff + 1); + dev->hwcursor_oddeven = 1; + } - svga->render8514(svga); + timer_advance_u64(&svga->timer, dev->dispofftime); + svga->cgastat |= 1; + dev->linepos = 1; - svga->x_add = svga->left_overscan; - ibm8514_render_overscan_left(dev, svga); - ibm8514_render_overscan_right(dev, svga); - svga->x_add = svga->left_overscan; + if (dev->dispon) { + dev->hdisp_on = 1; - if (dev->hwcursor_on) { - if (svga->hwcursor_draw) - svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); - dev->hwcursor_on--; - if (dev->hwcursor_on && dev->interlace) + dev->memaddr &= dev->vram_mask; + + if (dev->firstline == 2000) { + dev->firstline = dev->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (dev->hwcursor_on) + dev->changedvram[dev->memaddr >> 12] = dev->changedvram[(dev->memaddr >> 12) + 1] = dev->interlace ? 3 : 2; + + svga->render8514(svga); + + svga->x_add = svga->left_overscan; + ibm8514_render_overscan_left(dev, svga); + ibm8514_render_overscan_right(dev, svga); + svga->x_add = svga->left_overscan; + + if (dev->hwcursor_on) { + if (svga->hwcursor_draw) + svga->hwcursor_draw(svga, (dev->displine + svga->y_add + ((dev->hwcursor_latch.y >= 0) ? 0 : dev->hwcursor_latch.y)) & 2047); dev->hwcursor_on--; + if (dev->hwcursor_on && dev->interlace) + dev->hwcursor_on--; + } + + if (dev->lastline < dev->displine) + dev->lastline = dev->displine; } - if (dev->lastline < dev->displine) - dev->lastline = dev->displine; - } - - dev->displine++; - if (dev->interlace) dev->displine++; - if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - svga->vslines++; - if (dev->displine > 2000) - dev->displine = 0; - } else { - timer_advance_u64(&svga->timer, dev->dispontime); - if (dev->dispon) - svga->cgastat &= ~1; - dev->hdisp_on = 0; + if (dev->interlace) + dev->displine++; + if ((svga->cgastat & 8) && ((dev->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + svga->vslines++; + if (dev->displine > 2000) + dev->displine = 0; + } else { + timer_advance_u64(&svga->timer, dev->dispontime); + if (dev->dispon) + svga->cgastat &= ~1; + dev->hdisp_on = 0; - dev->linepos = 0; - if (dev->dispon) { - if (dev->scanline == dev->rowcount) { - dev->scanline = 0; - dev->memaddr_backup += (dev->rowoffset << 3); - if (dev->interlace) + dev->linepos = 0; + if (dev->dispon) { + if (dev->scanline == dev->rowcount) { + dev->scanline = 0; dev->memaddr_backup += (dev->rowoffset << 3); + if (dev->interlace) + dev->memaddr_backup += (dev->rowoffset << 3); - dev->memaddr_backup &= dev->vram_mask; - dev->memaddr = dev->memaddr_backup; - } else { - dev->scanline++; - dev->scanline &= 0x1f; - dev->memaddr = dev->memaddr_backup; - } - } - - dev->vc++; - dev->vc &= 0xfff; - - if (dev->vc == dev->dispend) { - dev->vblank_start(svga); - ibm8514_log("VBLANK irq.\n"); - dev->dispon = 0; - - for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { - if (dev->changedvram[x]) - dev->changedvram[x]--; + dev->memaddr_backup &= dev->vram_mask; + dev->memaddr = dev->memaddr_backup; + } else { + dev->scanline++; + dev->scanline &= 0x1f; + dev->memaddr = dev->memaddr_backup; + } } - if (svga->fullchange) - svga->fullchange--; - } - if (dev->vc == dev->v_syncstart) { - dev->dispon = 0; - svga->cgastat |= 8; - x = dev->h_disp; + dev->vc++; + dev->vc &= 0xfff; - if (dev->interlace && !dev->oddeven) - dev->lastline++; - if (dev->interlace && dev->oddeven) - dev->firstline--; + if (dev->vc == dev->dispend) { + dev->vblank_start(svga); + ibm8514_log("VBLANK irq.\n"); + dev->dispon = 0; - wx = x; - wy = dev->lastline - dev->firstline; - svga_doblit(wx, wy, svga); + for (x = 0; x < ((dev->vram_mask + 1) >> 12); x++) { + if (dev->changedvram[x]) + dev->changedvram[x]--; + } - dev->firstline = 2000; - dev->lastline = 0; + if (svga->fullchange) + svga->fullchange--; + } + if (dev->vc == dev->v_syncstart) { + dev->dispon = 0; + svga->cgastat |= 8; + x = dev->h_disp; - dev->firstline_draw = 2000; - dev->lastline_draw = 0; + if (dev->interlace && !dev->oddeven) + dev->lastline++; + if (dev->interlace && dev->oddeven) + dev->firstline--; - dev->oddeven ^= 1; + wx = x; + wy = dev->lastline - dev->firstline; + svga_doblit(wx, wy, svga); - svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; - svga->vslines = 0; + dev->firstline = 2000; + dev->lastline = 0; - if (dev->interlace && dev->oddeven) - dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); - else - dev->memaddr = dev->memaddr_backup = 0; + dev->firstline_draw = 2000; + dev->lastline_draw = 0; - dev->memaddr = (dev->memaddr << 2); - dev->memaddr_backup = (dev->memaddr_backup << 2); - } - if (dev->vc == dev->v_total) { - dev->vc = 0; - dev->scanline = (svga->crtc[0x8] & 0x1f); - dev->dispon = 1; - dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + dev->oddeven ^= 1; - svga->x_add = svga->left_overscan; + svga->monitor->mon_changeframecount = dev->interlace ? 3 : 2; + svga->vslines = 0; - dev->hwcursor_on = 0; - dev->hwcursor_latch = dev->hwcursor; + if (dev->interlace && dev->oddeven) + dev->memaddr = dev->memaddr_backup = (dev->rowoffset << 1); + else + dev->memaddr = dev->memaddr_backup = 0; + + dev->memaddr = (dev->memaddr << 2); + dev->memaddr_backup = (dev->memaddr_backup << 2); + } + if (dev->vc == dev->v_total) { + dev->vc = 0; + dev->scanline = (svga->crtc[0x8] & 0x1f); + dev->dispon = 1; + dev->displine = (dev->interlace && dev->oddeven) ? 1 : 0; + + svga->x_add = svga->left_overscan; + + dev->hwcursor_on = 0; + dev->hwcursor_latch = dev->hwcursor; + } } } } diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index a91a893df..8de29a2e6 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -3303,152 +3303,156 @@ xga_poll(void *priv) xga_log("XGA Poll=%d.\n", xga->on); if (xga->on) { - if (!xga->linepos) { - if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); - xga->hwcursor_oddeven = 0; - } - - if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { - xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); - xga->hwcursor_oddeven = 1; - } - - timer_advance_u64(&svga->timer, xga->dispofftime); - svga->cgastat |= 1; - xga->linepos = 1; - - if (xga->dispon) { - xga->h_disp_on = 1; - - xga->memaddr &= xga->vram_mask; - - if (xga->firstline == 2000) { - xga->firstline = xga->displine; - video_wait_for_buffer_monitor(svga->monitor_index); + if (svga->override) + svga_set_poll(svga); + else { + if (!xga->linepos) { + if (xga->displine == xga->hwcursor_latch.y && xga->hwcursor_latch.ena) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 32 : 0); + xga->hwcursor_oddeven = 0; } - if (xga->hwcursor_on) - xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; + if (xga->displine == (xga->hwcursor_latch.y + 1) && xga->hwcursor_latch.ena && xga->interlace) { + xga->hwcursor_on = xga->hwcursor_latch.cur_ysize - ((xga->hwcursor_latch.yoff & 0x20) ? 33 : 1); + xga->hwcursor_oddeven = 1; + } - svga->render_xga(svga); + timer_advance_u64(&svga->timer, xga->dispofftime); + svga->cgastat |= 1; + xga->linepos = 1; - svga->x_add = svga->left_overscan; - xga_render_overscan_left(xga, svga); - xga_render_overscan_right(xga, svga); - svga->x_add = svga->left_overscan; + if (xga->dispon) { + xga->h_disp_on = 1; - if (xga->hwcursor_on) { - xga_hwcursor_draw(svga, xga->displine + svga->y_add); - xga->hwcursor_on--; - if (xga->hwcursor_on && xga->interlace) + xga->memaddr &= xga->vram_mask; + + if (xga->firstline == 2000) { + xga->firstline = xga->displine; + video_wait_for_buffer_monitor(svga->monitor_index); + } + + if (xga->hwcursor_on) + xga->changedvram[xga->memaddr >> 12] = xga->changedvram[(xga->memaddr >> 12) + 1] = xga->interlace ? 3 : 2; + + svga->render_xga(svga); + + svga->x_add = svga->left_overscan; + xga_render_overscan_left(xga, svga); + xga_render_overscan_right(xga, svga); + svga->x_add = svga->left_overscan; + + if (xga->hwcursor_on) { + xga_hwcursor_draw(svga, xga->displine + svga->y_add); xga->hwcursor_on--; + if (xga->hwcursor_on && xga->interlace) + xga->hwcursor_on--; + } + + if (xga->lastline < xga->displine) + xga->lastline = xga->displine; } - if (xga->lastline < xga->displine) - xga->lastline = xga->displine; - } - - xga->displine++; - if (xga->interlace) xga->displine++; - if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) - svga->cgastat &= ~8; - if (xga->displine > 1500) - xga->displine = 0; - } else { - timer_advance_u64(&svga->timer, xga->dispontime); - if (xga->dispon) - svga->cgastat &= ~1; + if (xga->interlace) + xga->displine++; + if ((svga->cgastat & 8) && ((xga->displine & 0x0f) == (svga->crtc[0x11] & 0x0f)) && svga->vslines) + svga->cgastat &= ~8; + if (xga->displine > 1500) + xga->displine = 0; + } else { + timer_advance_u64(&svga->timer, xga->dispontime); + if (xga->dispon) + svga->cgastat &= ~1; - xga->h_disp_on = 0; + xga->h_disp_on = 0; - xga->linepos = 0; - if (xga->dispon) { - if (xga->scanline == xga->rowcount) { - xga->scanline = 0; + xga->linepos = 0; + if (xga->dispon) { + if (xga->scanline == xga->rowcount) { + xga->scanline = 0; - xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); - xga->memaddr_backup += (xga->rowoffset << 3); - if (xga->interlace) + xga_log("MA=%08x, MALATCH=%x.\n", xga->memaddr, xga->memaddr_latch); xga->memaddr_backup += (xga->rowoffset << 3); + if (xga->interlace) + xga->memaddr_backup += (xga->rowoffset << 3); - xga->memaddr_backup &= xga->vram_mask; - xga->memaddr = xga->memaddr_backup; - } else { - xga->scanline++; - xga->scanline &= 0x1f; - xga->memaddr = xga->memaddr_backup; + xga->memaddr_backup &= xga->vram_mask; + xga->memaddr = xga->memaddr_backup; + } else { + xga->scanline++; + xga->scanline &= 0x1f; + xga->memaddr = xga->memaddr_backup; + } } - } - xga->vc++; - xga->vc &= 0x7ff; + xga->vc++; + xga->vc &= 0x7ff; - if (xga->vc == xga->split) { - if (xga->interlace && xga->oddeven) - xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); - else - xga->memaddr = xga->memaddr_backup = 0; + if (xga->vc == xga->split) { + if (xga->interlace && xga->oddeven) + xga->memaddr = xga->memaddr_backup = (xga->rowoffset << 1); + else + xga->memaddr = xga->memaddr_backup = 0; - xga->memaddr = (xga->memaddr << 2); - xga->memaddr_backup = (xga->memaddr_backup << 2); + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); - xga->scanline = 0; - } - if (xga->vc == xga->dispend) { - xga->dispon = 0; - - for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { - if (xga->changedvram[x]) - xga->changedvram[x]--; + xga->scanline = 0; } - if (svga->fullchange) - svga->fullchange--; - } - if (xga->vc == xga->v_syncstart) { - xga->dispon = 0; - svga->cgastat |= 8; - x = xga->h_disp; + if (xga->vc == xga->dispend) { + xga->dispon = 0; - if (xga->interlace && !xga->oddeven) - xga->lastline++; - if (xga->interlace && xga->oddeven) - xga->firstline--; + for (x = 0; x < ((xga->vram_mask + 1) >> 12); x++) { + if (xga->changedvram[x]) + xga->changedvram[x]--; + } + if (svga->fullchange) + svga->fullchange--; + } + if (xga->vc == xga->v_syncstart) { + xga->dispon = 0; + svga->cgastat |= 8; + x = xga->h_disp; - wx = x; + if (xga->interlace && !xga->oddeven) + xga->lastline++; + if (xga->interlace && xga->oddeven) + xga->firstline--; - wy = xga->lastline - xga->firstline; - svga_doblit(wx, wy, svga); + wx = x; - xga->firstline = 2000; - xga->lastline = 0; + wy = xga->lastline - xga->firstline; + svga_doblit(wx, wy, svga); - xga->firstline_draw = 2000; - xga->lastline_draw = 0; + xga->firstline = 2000; + xga->lastline = 0; - xga->oddeven ^= 1; + xga->firstline_draw = 2000; + xga->lastline_draw = 0; - svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; + xga->oddeven ^= 1; - if (xga->interlace && xga->oddeven) - xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); - else - xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; + svga->monitor->mon_changeframecount = xga->interlace ? 3 : 2; - xga->memaddr = (xga->memaddr << 2); - xga->memaddr_backup = (xga->memaddr_backup << 2); - } - if (xga->vc == xga->v_total) { - xga->vc = 0; - xga->scanline = 0; - xga->dispon = 1; - xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; + if (xga->interlace && xga->oddeven) + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch + (xga->rowoffset << 1); + else + xga->memaddr = xga->memaddr_backup = xga->memaddr_latch; - svga->x_add = svga->left_overscan; + xga->memaddr = (xga->memaddr << 2); + xga->memaddr_backup = (xga->memaddr_backup << 2); + } + if (xga->vc == xga->v_total) { + xga->vc = 0; + xga->scanline = 0; + xga->dispon = 1; + xga->displine = (xga->interlace && xga->oddeven) ? 1 : 0; - xga->hwcursor_on = 0; - xga->hwcursor_latch = xga->hwcursor; + svga->x_add = svga->left_overscan; + + xga->hwcursor_on = 0; + xga->hwcursor_latch = xga->hwcursor; + } } } } else From 60d502daad92bcf4e1a8c17810c1bf14f2f9b6fe Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 Sep 2025 00:28:05 +0200 Subject: [PATCH 045/138] (S)VGA pel panning: values above 7 behave like 7. --- src/video/vid_svga.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d3a95f0bb..cbbf98ab4 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1587,6 +1587,8 @@ svga_poll(void *priv) svga->half_pixel = 0; svga->scrollcache &= 0x07; } else { + if (svga->scrollcache > 7) + svga->scrollcache = 7; svga->half_pixel = svga->scrollcache & 0x01; svga->scrollcache = (svga->scrollcache & 0x06) >> 1; } From 06215a0697cae8938427b70a7e69e7c837b4c99e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Wed, 10 Sep 2025 00:54:54 +0200 Subject: [PATCH 046/138] Update sdl_joystick.c --- src/qt/sdl_joystick.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index f1ba0380f..4b2748760 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -50,7 +50,7 @@ joystick_init(void) SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); #endif - if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { + if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) { return; } joysticks_present = SDL_NumJoysticks(); From ea7cb1cc55f3b81ea415ec251836b999f00e3c36 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 18:55:59 -0400 Subject: [PATCH 047/138] Some more clang formatting --- src/CMakeLists.txt | 25 +++++- src/floppy/fdd.c | 70 ++++++++-------- src/sound/audio4.c | 194 ++++++++++++++++++++++++-------------------- src/sound/openal.c | 82 +++++++++++-------- src/sound/sndio.c | 182 ++++++++++++++++++++++------------------- src/sound/sound.c | 1 - src/sound/xaudio2.c | 25 +++--- 7 files changed, 321 insertions(+), 258 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 724e1fda6..ec3b2c628 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -103,8 +103,29 @@ if(INSTRUMENT) add_compile_definitions(USE_INSTRUMENT) endif() -target_link_libraries(86Box cpu chipset mch dev mem fdd game cdrom rdisk mo hdd - net print scsi sio snd utils vid voodoo plat ui) +target_link_libraries(86Box + cpu + chipset + mch + dev + mem + fdd + game + cdrom + rdisk + mo + hdd + net + print + scsi + sio + snd + utils + vid + voodoo + plat + ui +) if(HAIKU) target_link_libraries(86Box be) diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 8bc946388..bc81c8662 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -105,39 +105,39 @@ static const struct void (*close)(int drive); int size; } loaders[] = { - { "001", img_load, img_close, -1}, - { "002", img_load, img_close, -1}, - { "003", img_load, img_close, -1}, - { "004", img_load, img_close, -1}, - { "005", img_load, img_close, -1}, - { "006", img_load, img_close, -1}, - { "007", img_load, img_close, -1}, - { "008", img_load, img_close, -1}, - { "009", img_load, img_close, -1}, - { "010", img_load, img_close, -1}, - { "12", img_load, img_close, -1}, - { "144", img_load, img_close, -1}, - { "360", img_load, img_close, -1}, - { "720", img_load, img_close, -1}, - { "86F", d86f_load, d86f_close, -1}, - { "BIN", img_load, img_close, -1}, - { "CQ", img_load, img_close, -1}, - { "CQM", img_load, img_close, -1}, - { "DDI", img_load, img_close, -1}, - { "DSK", img_load, img_close, -1}, - { "FDI", fdi_load, fdi_close, -1}, - { "FDF", img_load, img_close, -1}, - { "FLP", img_load, img_close, -1}, - { "HDM", img_load, img_close, -1}, - { "IMA", img_load, img_close, -1}, - { "IMD", imd_load, imd_close, -1}, - { "IMG", img_load, img_close, -1}, - { "JSON", pcjs_load, pcjs_close, -1}, - { "MFM", mfm_load, mfm_close, -1}, - { "TD0", td0_load, td0_close, -1}, - { "VFD", img_load, img_close, -1}, - { "XDF", img_load, img_close, -1}, - { 0, 0, 0, 0 } + { "001", img_load, img_close, -1 }, + { "002", img_load, img_close, -1 }, + { "003", img_load, img_close, -1 }, + { "004", img_load, img_close, -1 }, + { "005", img_load, img_close, -1 }, + { "006", img_load, img_close, -1 }, + { "007", img_load, img_close, -1 }, + { "008", img_load, img_close, -1 }, + { "009", img_load, img_close, -1 }, + { "010", img_load, img_close, -1 }, + { "12", img_load, img_close, -1 }, + { "144", img_load, img_close, -1 }, + { "360", img_load, img_close, -1 }, + { "720", img_load, img_close, -1 }, + { "86F", d86f_load, d86f_close, -1 }, + { "BIN", img_load, img_close, -1 }, + { "CQ", img_load, img_close, -1 }, + { "CQM", img_load, img_close, -1 }, + { "DDI", img_load, img_close, -1 }, + { "DSK", img_load, img_close, -1 }, + { "FDI", fdi_load, fdi_close, -1 }, + { "FDF", img_load, img_close, -1 }, + { "FLP", img_load, img_close, -1 }, + { "HDM", img_load, img_close, -1 }, + { "IMA", img_load, img_close, -1 }, + { "IMD", imd_load, imd_close, -1 }, + { "IMG", img_load, img_close, -1 }, + { "JSON", pcjs_load, pcjs_close, -1 }, + { "MFM", mfm_load, mfm_close, -1 }, + { "TD0", td0_load, td0_close, -1 }, + { "VFD", img_load, img_close, -1 }, + { "XDF", img_load, img_close, -1 }, + { 0, 0, 0, 0 } }; static const struct { @@ -211,7 +211,7 @@ fdd_get_internal_name(int type) int fdd_get_from_internal_name(char *s) { - int c = 0; + int c = 0; while (strlen(drive_types[c].internal_name)) { if (!strcmp((char *) drive_types[c].internal_name, s)) @@ -466,7 +466,7 @@ fdd_load(int drive, char *fn) if (!fn) return; if (strstr(fn, "wp://") == fn) { - offs = 5; + offs = 5; ui_writeprot[drive] = 1; } fn += offs; diff --git a/src/sound/audio4.c b/src/sound/audio4.c index 4e74d2c0c..c76d3253f 100644 --- a/src/sound/audio4.c +++ b/src/sound/audio4.c @@ -34,128 +34,146 @@ #endif #define I_NORMAL 0 -#define I_MUSIC 1 -#define I_WT 2 -#define I_CD 3 -#define I_MIDI 4 +#define I_MUSIC 1 +#define I_WT 2 +#define I_CD 3 +#define I_MIDI 4 -static int audio[5] = {-1, -1, -1, -1, -1}; +static int audio[5] = { -1, -1, -1, -1, -1 }; #ifdef USE_NEW_API static struct audio_swpar info[5]; #else static audio_info_t info[5]; #endif -static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0}; +static int freqs[5] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0 }; -void closeal(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - if(audio[i] != -1){ - close(audio[i]); - } - audio[i] = -1; - } +void +closeal(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + if (audio[i] != -1) + close(audio[i]); + + audio[i] = -1; + } } -void inital(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - audio[i] = open("/dev/audio", O_WRONLY); - if(audio[i] == -1) audio[i] = open("/dev/audio0", O_WRONLY); - if(audio[i] != -1){ +void +inital(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + audio[i] = open("/dev/audio", O_WRONLY); + if (audio[i] == -1) + audio[i] = open("/dev/audio0", O_WRONLY); + if (audio[i] != -1) { #ifdef USE_NEW_API - AUDIO_INITPAR(&info[i]); - ioctl(audio[i], AUDIO_GETPAR, &info[i]); - info[i].sig = 1; - info[i].bits = 16; - info[i].pchan = 2; - info[i].bps = 2; - ioctl(audio[i], AUDIO_SETPAR, &info[i]); + AUDIO_INITPAR(&info[i]); + ioctl(audio[i], AUDIO_GETPAR, &info[i]); + info[i].sig = 1; + info[i].bits = 16; + info[i].pchan = 2; + info[i].bps = 2; + ioctl(audio[i], AUDIO_SETPAR, &info[i]); #else - AUDIO_INITINFO(&info[i]); + AUDIO_INITINFO(&info[i]); #if defined(__NetBSD__) && (__NetBSD_Version__ >= 900000000) - ioctl(audio[i], AUDIO_GETFORMAT, &info[i]); + ioctl(audio[i], AUDIO_GETFORMAT, &info[i]); #else - ioctl(audio[i], AUDIO_GETINFO, &info[i]); + ioctl(audio[i], AUDIO_GETINFO, &info[i]); #endif - info[i].play.channels = 2; - info[i].play.precision = 16; - info[i].play.encoding = AUDIO_ENCODING_SLINEAR; - info[i].hiwat = 5; - info[i].lowat = 3; - ioctl(audio[i], AUDIO_SETINFO, &info[i]); + info[i].play.channels = 2; + info[i].play.precision = 16; + info[i].play.encoding = AUDIO_ENCODING_SLINEAR; + info[i].hiwat = 5; + info[i].lowat = 3; + ioctl(audio[i], AUDIO_SETINFO, &info[i]); #endif - } - } + } + } } -void givealbuffer_common(const void *buf, const uint8_t src, const int size){ - const int freq = freqs[src]; - int16_t* output; - int output_size; - int16_t* conv; - int conv_size; - int i; - double gain; - int target_rate; - if(audio[src] == -1) return; +void +givealbuffer_common(const void *buf, const uint8_t src, const int size) +{ + const int freq = freqs[src]; + int16_t* output; + int output_size; + int16_t* conv; + int conv_size; + double gain; + int target_rate; - gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + if(audio[src] == -1) + return; - if(sound_is_float){ - float* input = (float*)buf; - conv_size = sizeof(int16_t) * size; - conv = malloc(conv_size); - for(i = 0; i < conv_size / sizeof(int16_t); i++){ - conv[i] = 32767 * input[i]; - } - }else{ - conv_size = size * sizeof(int16_t); - conv = malloc(conv_size); - memcpy(conv, buf, conv_size); - } + gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + + if (sound_is_float) { + float* input = (float*)buf; + conv_size = sizeof(int16_t) * size; + conv = malloc(conv_size); + for (int i = 0; i < conv_size / sizeof(int16_t); i++) + conv[i] = 32767 * input[i]; + } else { + conv_size = size * sizeof(int16_t); + conv = malloc(conv_size); + memcpy(conv, buf, conv_size); + } #ifdef USE_NEW_API - target_rate = info[src].rate; + target_rate = info[src].rate; #else - target_rate = info[src].play.sample_rate; + target_rate = info[src].play.sample_rate; #endif - output_size = (double)conv_size * target_rate / freq; - output_size -= output_size % 4; - output = malloc(output_size); - - for(i = 0; i < output_size / sizeof(int16_t) / 2; i++){ - int ind = i * freq / target_rate * 2; - output[i * 2 + 0] = conv[ind + 0] * gain; - output[i * 2 + 1] = conv[ind + 1] * gain; - } + output_size = (double) conv_size * target_rate / freq; + output_size -= output_size % 4; + output = malloc(output_size); + + for (int i = 0; i < output_size / sizeof(int16_t) / 2; i++) { + int ind = i * freq / target_rate * 2; + output[i * 2 + 0] = conv[ind + 0] * gain; + output[i * 2 + 1] = conv[ind + 1] * gain; + } - write(audio[src], output, output_size); + write(audio[src], output, output_size); - free(conv); - free(output); + free(conv); + free(output); } -void givealbuffer(const void *buf){ - givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); +void +givealbuffer(const void *buf) +{ + givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); } -void givealbuffer_music(const void *buf){ - givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); +void +givealbuffer_music(const void *buf) +{ + givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); } -void givealbuffer_wt(const void *buf){ - givealbuffer_common(buf, I_WT, WTBUFLEN << 1); +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, I_WT, WTBUFLEN << 1); } -void givealbuffer_cd(const void *buf){ - givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); +void +givealbuffer_cd(const void *buf) +{ + givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); } -void givealbuffer_midi(const void *buf, const uint32_t size){ - givealbuffer_common(buf, I_MIDI, (int) size); + +void +givealbuffer_midi(const void *buf, const uint32_t size) +{ + givealbuffer_common(buf, I_MIDI, (int) size); } - -void al_set_midi(const int freq, UNUSED(const int buf_size)){ - freqs[I_MIDI] = freq; + +void +al_set_midi(const int freq, UNUSED(const int buf_size)) +{ + freqs[I_MIDI] = freq; } diff --git a/src/sound/openal.c b/src/sound/openal.c index 90f626362..c2addb270 100644 --- a/src/sound/openal.c +++ b/src/sound/openal.c @@ -37,6 +37,12 @@ #define FREQ SOUND_FREQ #define BUFLEN SOUNDBUFLEN +#define I_NORMAL 0 +#define I_MUSIC 1 +#define I_WT 2 +#define I_CD 3 +#define I_MIDI 4 + ALuint buffers[4]; /* front and back buffers */ ALuint buffers_music[4]; /* front and back buffers */ ALuint buffers_wt[4]; /* front and back buffers */ @@ -124,7 +130,7 @@ inital(void) int16_t *cd_buf_int16 = NULL; int16_t *midi_buf_int16 = NULL; - int init_midi = 0; + int init_midi = 0; if (initialized) return; @@ -166,32 +172,36 @@ inital(void) else alGenSources(4, source); - alSource3f(source[0], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[0], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[0], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[0], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[0], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[1], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[1], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[1], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[1], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[1], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[2], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[2], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[2], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[2], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[2], AL_SOURCE_RELATIVE, AL_TRUE); - alSource3f(source[3], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[3], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[3], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[3], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[3], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[I_NORMAL], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_NORMAL], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_NORMAL], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_NORMAL], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_NORMAL], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_MUSIC], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MUSIC], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MUSIC], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_MUSIC], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_MUSIC], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_WT], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_WT], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_WT], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_WT], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_WT], AL_SOURCE_RELATIVE, AL_TRUE); + + alSource3f(source[I_CD], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_CD], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_CD], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_CD], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_CD], AL_SOURCE_RELATIVE, AL_TRUE); + if (init_midi) { - alSource3f(source[4], AL_POSITION, 0.0f, 0.0f, 0.0f); - alSource3f(source[4], AL_VELOCITY, 0.0f, 0.0f, 0.0f); - alSource3f(source[4], AL_DIRECTION, 0.0f, 0.0f, 0.0f); - alSourcef(source[4], AL_ROLLOFF_FACTOR, 0.0f); - alSourcei(source[4], AL_SOURCE_RELATIVE, AL_TRUE); + alSource3f(source[I_MIDI], AL_POSITION, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MIDI], AL_VELOCITY, 0.0f, 0.0f, 0.0f); + alSource3f(source[I_MIDI], AL_DIRECTION, 0.0f, 0.0f, 0.0f); + alSourcef(source[I_MIDI], AL_ROLLOFF_FACTOR, 0.0f); + alSourcei(source[I_MIDI], AL_SOURCE_RELATIVE, AL_TRUE); } if (sound_is_float) { @@ -228,18 +238,18 @@ inital(void) } } - alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_music); - alSourceQueueBuffers(source[2], 4, buffers_wt); - alSourceQueueBuffers(source[3], 4, buffers_cd); + alSourceQueueBuffers(source[I_NORMAL], 4, buffers); + alSourceQueueBuffers(source[I_MUSIC], 4, buffers_music); + alSourceQueueBuffers(source[I_WT], 4, buffers_wt); + alSourceQueueBuffers(source[I_CD], 4, buffers_cd); if (init_midi) - alSourceQueueBuffers(source[4], 4, buffers_midi); - alSourcePlay(source[0]); - alSourcePlay(source[1]); - alSourcePlay(source[2]); - alSourcePlay(source[3]); + alSourceQueueBuffers(source[I_MIDI], 4, buffers_midi); + alSourcePlay(source[I_NORMAL]); + alSourcePlay(source[I_MUSIC]); + alSourcePlay(source[I_WT]); + alSourcePlay(source[I_CD]); if (init_midi) - alSourcePlay(source[4]); + alSourcePlay(source[I_MIDI]); if (sound_is_float) { if (init_midi) diff --git a/src/sound/sndio.c b/src/sound/sndio.c index 2fe1434df..7459dc130 100644 --- a/src/sound/sndio.c +++ b/src/sound/sndio.c @@ -32,109 +32,125 @@ #define I_CD 3 #define I_MIDI 4 -static struct sio_hdl* audio[5] = {NULL, NULL, NULL, NULL, NULL}; +static struct sio_hdl* audio[5] = { NULL, NULL, NULL, NULL, NULL }; static struct sio_par info[5]; -static int freqs[5] = {SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0}; +static int freqs[5] = { SOUND_FREQ, MUSIC_FREQ, WT_FREQ, CD_FREQ, 0 }; -void closeal(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - if(audio[i] != NULL){ - sio_close(audio[i]); - } - audio[i] = NULL; - } +void +closeal(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + if (audio[i] != NULL) + sio_close(audio[i]); + + audio[i] = NULL; + } } -void inital(void){ - int i; - for(i = 0; i < sizeof(audio) / sizeof(audio[0]); i++){ - audio[i] = sio_open(SIO_DEVANY, SIO_PLAY, 0); - if(audio[i] != NULL){ - int rate; - int max_frames; - sio_getpar(audio[i], &info[i]); - rate = info[i].rate; - max_frames = info[i].bufsz; - sio_initpar(&info[i]); - info[i].sig = 1; - info[i].bits = 16; - info[i].pchan = 2; - info[i].rate = rate; - info[i].appbufsz = max_frames; - sio_setpar(audio[i], &info[i]); - sio_getpar(audio[i], &info[i]); - if(!sio_start(audio[i])){ - sio_close(audio[i]); - audio[i] = NULL; - } - } - } +void +inital(void) +{ + for (int i = 0; i < sizeof(audio) / sizeof(audio[0]); i++) { + audio[i] = sio_open(SIO_DEVANY, SIO_PLAY, 0); + if (audio[i] != NULL) { + int rate; + int max_frames; + sio_getpar(audio[i], &info[i]); + rate = info[i].rate; + max_frames = info[i].bufsz; + sio_initpar(&info[i]); + info[i].sig = 1; + info[i].bits = 16; + info[i].pchan = 2; + info[i].rate = rate; + info[i].appbufsz = max_frames; + sio_setpar(audio[i], &info[i]); + sio_getpar(audio[i], &info[i]); + if (!sio_start(audio[i])) { + sio_close(audio[i]); + audio[i] = NULL; + } + } + } } -void givealbuffer_common(const void *buf, const uint8_t src, const int size){ - const int freq = freqs[src]; - int16_t* output; - int output_size; - int16_t* conv; - int conv_size; - int i; - double gain; - int target_rate; - if(audio[src] == NULL) return; +void +givealbuffer_common(const void *buf, const uint8_t src, const int size) +{ + const int freq = freqs[src]; + int16_t* output; + int output_size; + int16_t* conv; + int conv_size; + double gain; + int target_rate; + if (audio[src] == NULL) + return; - gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); + gain = sound_muted ? 0.0 : pow(10.0, (double) sound_gain / 20.0); - if(sound_is_float){ - float* input = (float*)buf; - conv_size = sizeof(int16_t) * size; - conv = malloc(conv_size); - for(i = 0; i < conv_size / sizeof(int16_t); i++){ - conv[i] = 32767 * input[i]; - } - }else{ - conv_size = size * sizeof(int16_t); - conv = malloc(conv_size); - memcpy(conv, buf, conv_size); - } + if (sound_is_float) { + float* input = (float*) buf; + conv_size = sizeof(int16_t) * size; + conv = malloc(conv_size); + for (int i = 0; i < conv_size / sizeof(int16_t); i++) + conv[i] = 32767 * input[i]; + } else { + conv_size = size * sizeof(int16_t); + conv = malloc(conv_size); + memcpy(conv, buf, conv_size); + } - target_rate = info[src].rate; + target_rate = info[src].rate; - output_size = (double)conv_size * target_rate / freq; - output_size -= output_size % 4; - output = malloc(output_size); - - for(i = 0; i < output_size / sizeof(int16_t) / 2; i++){ - int ind = i * freq / target_rate * 2; - output[i * 2 + 0] = conv[ind + 0] * gain; - output[i * 2 + 1] = conv[ind + 1] * gain; - } + output_size = (double) conv_size * target_rate / freq; + output_size -= output_size % 4; + output = malloc(output_size); + + for (int i = 0; i < output_size / sizeof(int16_t) / 2; i++) { + int ind = i * freq / target_rate * 2; + output[i * 2 + 0] = conv[ind + 0] * gain; + output[i * 2 + 1] = conv[ind + 1] * gain; + } - sio_write(audio[src], output, output_size); + sio_write(audio[src], output, output_size); - free(conv); - free(output); + free(conv); + free(output); } -void givealbuffer(const void *buf){ - givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); +void +givealbuffer(const void *buf) +{ + givealbuffer_common(buf, I_NORMAL, SOUNDBUFLEN << 1); } -void givealbuffer_music(const void *buf){ - givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); +void +givealbuffer_music(const void *buf) +{ + givealbuffer_common(buf, I_MUSIC, MUSICBUFLEN << 1); } -void givealbuffer_wt(const void *buf){ - givealbuffer_common(buf, I_WT, WTBUFLEN << 1); +void +givealbuffer_wt(const void *buf) +{ + givealbuffer_common(buf, I_WT, WTBUFLEN << 1); } -void givealbuffer_cd(const void *buf){ - givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); +void +givealbuffer_cd(const void *buf) +{ + givealbuffer_common(buf, I_CD, CD_BUFLEN << 1); } -void givealbuffer_midi(const void *buf, const uint32_t size){ - givealbuffer_common(buf, I_MIDI, (int) size); + +void +givealbuffer_midi(const void *buf, const uint32_t size) +{ + givealbuffer_common(buf, I_MIDI, (int) size); } - -void al_set_midi(const int freq, UNUSED(const int buf_size)){ - freqs[I_MIDI] = freq; + +void +al_set_midi(const int freq, UNUSED(const int buf_size)) +{ + freqs[I_MIDI] = freq; } diff --git a/src/sound/sound.c b/src/sound/sound.c index c81dc47b0..579056359 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -55,7 +55,6 @@ int wavetable_pos_global = 0; int sound_gain = 0; static sound_handler_t sound_handlers[8]; - static sound_handler_t music_handlers[8]; static sound_handler_t wavetable_handlers[8]; diff --git a/src/sound/xaudio2.c b/src/sound/xaudio2.c index 2aee97efc..b526fa72f 100644 --- a/src/sound/xaudio2.c +++ b/src/sound/xaudio2.c @@ -39,8 +39,8 @@ static void *xaudio2_handle = NULL; static HRESULT(WINAPI *pXAudio2Create)(IXAudio2 **ppXAudio2, uint32_t Flags, XAUDIO2_PROCESSOR XAudio2Processor); static dllimp_t xaudio2_imports[] = { - {"XAudio2Create", &pXAudio2Create}, - { NULL, NULL }, + {"XAudio2Create", &pXAudio2Create }, + { NULL, NULL }, }; # define XAudio2Create pXAudio2Create #endif @@ -119,22 +119,18 @@ void inital(void) { #if defined(_WIN32) && !defined(USE_FAUDIO) - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) xaudio2_handle = dynld_module("xaudio2_9.dll", xaudio2_imports); - } - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) xaudio2_handle = dynld_module("xaudio2_9redist.dll", xaudio2_imports); - } - if (xaudio2_handle == NULL) { + if (xaudio2_handle == NULL) return; - } #endif - if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) { + if (XAudio2Create(&xaudio2, 0, XAUDIO2_DEFAULT_PROCESSOR)) return; - } if (IXAudio2_CreateMasteringVoice(xaudio2, &mastervoice, 2, FREQ, 0, 0, NULL, 0)) { IXAudio2_Release(xaudio2); @@ -209,6 +205,7 @@ closeal(void) { if (!initialized) return; + initialized = 0; (void) IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW); (void) IXAudio2SourceVoice_FlushSourceBuffers(srcvoice); @@ -229,9 +226,11 @@ closeal(void) IXAudio2SourceVoice_DestroyVoice(srcvoice); IXAudio2MasteringVoice_DestroyVoice(mastervoice); IXAudio2_Release(xaudio2); - srcvoice = srcvoicecd = srcvoicemidi = NULL; - mastervoice = NULL; - xaudio2 = NULL; + srcvoice = NULL; + srcvoicecd = NULL; + srcvoicemidi = NULL; + mastervoice = NULL; + xaudio2 = NULL; #if defined(_WIN32) && !defined(USE_FAUDIO) dynld_close(xaudio2_handle); From 1e0f92185f11e3030018c27d415075e8b8f35f05 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:18:14 -0400 Subject: [PATCH 048/138] Sensible defaults in cartridge.c --- src/device/cartridge.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device/cartridge.c b/src/device/cartridge.c index 00464026a..cb3c5e412 100644 --- a/src/device/cartridge.c +++ b/src/device/cartridge.c @@ -92,8 +92,8 @@ cart_image_close(int drive) static void cart_image_load(int drive, char *fn) { - FILE *fp; - uint32_t size; + FILE *fp = NULL; + uint32_t size = 0; uint32_t base = 0x00000000; cart_image_close(drive); @@ -137,7 +137,7 @@ cart_image_load(int drive, char *fn) static void cart_load_common(int drive, char *fn, uint8_t hard_reset) { - FILE *fp; + FILE *fp = NULL; cartridge_log("Cartridge: loading drive %d with '%s'\n", drive, fn); From 6f9930417dcc2e09900c200ada1e6d5f0602f069 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:35:15 -0400 Subject: [PATCH 049/138] A few EMU8000 Cleanups --- src/include/86box/snd_emu8k.h | 10 +++++---- src/sound/snd_emu8k.c | 39 +++++++++++++++++------------------ 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/include/86box/snd_emu8k.h b/src/include/86box/snd_emu8k.h index 4bad23b97..fcbad4cfa 100644 --- a/src/include/86box/snd_emu8k.h +++ b/src/include/86box/snd_emu8k.h @@ -199,8 +199,8 @@ typedef struct emu8k_voice_t { * something, similarly to targets and current, but... of what? * what is curious is that if they are already zero, they are not written to, so it really * looks like they are information about the status of the channel. (lfo position maybe?) */ - uint32_t unknown_data0_4; - uint32_t unknown_data0_5; + uint32_t z2; + uint32_t z1; union { uint32_t psst; struct { @@ -229,7 +229,7 @@ typedef struct emu8k_voice_t { }; #define CCCA_FILTQ_GET(ccca) (ccca >> 28) #define CCCA_FILTQ_SET(ccca, q) ccca = (ccca & 0x0FFFFFFF) | (q << 28) -/* Bit 27 should always be zero */ +/* Bit 27 should always be zero on EMU8000 */ #define CCCA_DMA_ACTIVE(ccca) (ccca & 0x04000000) #define CCCA_DMA_WRITE_MODE(ccca) (ccca & 0x02000000) #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca & 0x01000000) @@ -316,7 +316,9 @@ typedef struct emu8k_voice_t { int env_engine_on; - emu8k_mem_internal_t addr, loop_start, loop_end; + emu8k_mem_internal_t addr; + emu8k_mem_internal_t loop_start; + emu8k_mem_internal_t loop_end; int32_t initial_att; int32_t initial_filter; diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 822abeeaa..c3efdaaff 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -556,11 +556,11 @@ emu8k_inw(uint16_t addr, void *priv) return ret; case 4: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4); + READ16(addr, emu8k->voice[emu8k->cur_voice].z2); return ret; case 5: - READ16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5); + READ16(addr, emu8k->voice[emu8k->cur_voice].z1); return ret; case 6: @@ -888,11 +888,11 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) return; case 4: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_4, val); + WRITE16(addr, emu8k->voice[emu8k->cur_voice].z2, val); return; case 5: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].unknown_data0_5, val); + WRITE16(addr, emu8k->voice[emu8k->cur_voice].z1, val); return; case 6: @@ -1006,7 +1006,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) case 0x9: emu8k->reverb_engine.reflections[0].feedback = (val & 0xF) / 15.0; break; - case 0xB: + case 0xB: #if 0 emu8k->reverb_engine.reflections[0].feedback_r = (val&0xF)/15.0; #endif @@ -1050,7 +1050,7 @@ emu8k_outw(uint16_t addr, uint16_t val, void *priv) case 1: emu8k->reverb_engine.refl_in_amp = val & 0xFF; break; - case 3: + case 3: #if 0 emu8k->reverb_engine.refl_in_amp_r = val&0xFF; #endif @@ -1811,11 +1811,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[1] += (emu_voice->filt_buffer[0] * coef0) >> 24; emu_voice->filt_buffer[0] += (vhp * coef0) >> 24; dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #elif defined FILTER_MOOG @@ -1823,15 +1822,15 @@ emu8k_update(emu8k_t *emu8k) dat <<= 8; dat -= (coef2 * emu_voice->filt_buffer[4]) >> 24; /*feedback*/ - int64_t t1 = emu_voice->filt_buffer[1]; + int64_t t1 = emu_voice->filt_buffer[1]; emu_voice->filt_buffer[1] = ((dat + emu_voice->filt_buffer[0]) * coef0 - emu_voice->filt_buffer[1] * coef1) >> 24; emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); - int64_t t2 = emu_voice->filt_buffer[2]; + int64_t t2 = emu_voice->filt_buffer[2]; emu_voice->filt_buffer[2] = ((emu_voice->filt_buffer[1] + t1) * coef0 - emu_voice->filt_buffer[2] * coef1) >> 24; emu_voice->filt_buffer[2] = ClipBuffer(emu_voice->filt_buffer[2]); - int64_t t3 = emu_voice->filt_buffer[3]; + int64_t t3 = emu_voice->filt_buffer[3]; emu_voice->filt_buffer[3] = ((emu_voice->filt_buffer[2] + t2) * coef0 - emu_voice->filt_buffer[3] * coef1) >> 24; emu_voice->filt_buffer[3] = ClipBuffer(emu_voice->filt_buffer[3]); @@ -1841,11 +1840,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[0] = ClipBuffer(dat); dat = (int32_t) (emu_voice->filt_buffer[4] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #elif defined FILTER_CONSTANT @@ -1864,11 +1862,10 @@ emu8k_update(emu8k_t *emu8k) emu_voice->filt_buffer[1] = ClipBuffer(emu_voice->filt_buffer[1]); dat = (int32_t) (emu_voice->filt_buffer[1] >> 8); - if (dat > 32767) { + if (dat > 32767) dat = 32767; - } else if (dat < -32768) { + else if (dat < -32768) dat = -32768; - } #endif } @@ -2372,6 +2369,8 @@ emu8k_init(emu8k_t *emu8k, uint16_t emu_addr, int onboard_ram) void emu8k_close(emu8k_t *emu8k) { - free(emu8k->rom); - free(emu8k->ram); + if (emu8k->rom) + free(emu8k->rom); + if (emu8k->ram) + free(emu8k->ram); } From af007b12e75f754f994fe1a200145419306d435c Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:37:41 -0400 Subject: [PATCH 050/138] path_get_basename helper function --- src/include/86box/path.h | 3 ++- src/qt/qt_platform.cpp | 7 +++++++ src/unix/unix.c | 3 ++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/include/86box/path.h b/src/include/86box/path.h index f1c5e4177..ef66c0a30 100644 --- a/src/include/86box/path.h +++ b/src/include/86box/path.h @@ -1,3 +1,4 @@ +extern char *path_get_basename(const char *path); extern void path_get_dirname(char *dest, const char *path); extern char *path_get_filename(char *s); extern char *path_get_extension(char *s); @@ -5,4 +6,4 @@ extern void path_append_filename(char *dest, const char *s1, const char *s2); extern void path_slash(char *path); extern const char *path_get_slash(char *path); extern void path_normalize(char *path); -extern int path_abs(char *path); \ No newline at end of file +extern int path_abs(char *path); diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 03bc68390..240315faa 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -267,6 +267,13 @@ plat_getcwd(char *bufp, int max) return 0; } +char * +path_get_basename(const char *path) +{ + QFileInfo fi(path); + return fi.fileName().toUtf8().data(); +} + void path_get_dirname(char *dest, const char *path) { diff --git a/src/unix/unix.c b/src/unix/unix.c index de35f4e93..4f3990590 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -351,7 +351,7 @@ plat_put_backslash(char *s) /* Return the last element of a pathname. */ char * -plat_get_basename(const char *path) +path_get_basename(const char *path) { int c = (int) strlen(path); @@ -1420,6 +1420,7 @@ main(int argc, char **argv) f_rl_callback_handler_remove(); return 0; } + char * plat_vidapi_name(UNUSED(int i)) { From f937b8124627a4b32795cdaf4e18d24c9e976307 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:49:39 -0400 Subject: [PATCH 051/138] PCjr Cleanups --- src/machine/m_pcjr.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/machine/m_pcjr.c b/src/machine/m_pcjr.c index b7d840224..9dba8795f 100644 --- a/src/machine/m_pcjr.c +++ b/src/machine/m_pcjr.c @@ -774,14 +774,14 @@ pit_irq0_timer_pcjr(int new_out, int old_out, UNUSED(void *priv)) static const device_config_t pcjr_config[] = { // clang-format off { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = PCJR_RGB, - .file_filter = "", - .spinner = { 0 }, - .selection = { + .name = "display_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = PCJR_RGB, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { .description = "RGB", .value = PCJR_RGB }, { .description = "Composite", .value = PCJR_COMPOSITE }, { .description = "RGB (no brown)", .value = PCJR_RGB_NO_BROWN }, @@ -807,11 +807,11 @@ static const device_config_t pcjr_config[] = { .bios = { { 0 } } }, { - .name = "apply_hd", - .description = "Apply overscan deltas", - .type = CONFIG_BINARY, - .default_string = "", - .default_int = 1 + .name = "apply_hd", + .description = "Apply overscan deltas", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } // clang-format on From cb5a12e2a09ccf5d9c43c8e3d79aae5ce57568e6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Tue, 9 Sep 2025 19:59:42 -0400 Subject: [PATCH 052/138] Improve the macos joystick fix --- src/qt/sdl_joystick.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/qt/sdl_joystick.c b/src/qt/sdl_joystick.c index 4b2748760..fddb730e7 100644 --- a/src/qt/sdl_joystick.c +++ b/src/qt/sdl_joystick.c @@ -50,9 +50,13 @@ joystick_init(void) SDL_SetHint(SDL_HINT_JOYSTICK_THREAD, "1"); #endif - if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) { +#ifdef __APPLE__ + if (SDL_InitSubSystem(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0) +#else + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) +#endif return; - } + joysticks_present = SDL_NumJoysticks(); memset(sdl_joy, 0, sizeof(sdl_joy)); From b3cf1db56863a8e90debd68f1ce360769335fb05 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:49:05 +0800 Subject: [PATCH 053/138] Add NEC PowerMate V2xxx/P2xxx! Let's Add NEC PowerMate V2xxx/P2xxx! It was based on Intel CU430HX (Cumberland). --- src/machine/m_at_socket7.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index b0651a8af..6101513cd 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -155,6 +155,10 @@ static const device_config_t cu430hx_config[] = { .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1003DK08.BIO", "roms/machines/cu430hx/1003DK08.BI1", "roms/machines/cu430hx/1003DK08.BI2", "roms/machines/cu430hx/1003DK08.BI3", "roms/machines/cu430hx/1003DK08.RCV", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.04.DK0K (NEC PowerMate V2xxx/P2xxx)", .internal_name = "powermatev2p2", .bios_type = BIOS_NORMAL, + .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1004DK0K.BIO", "roms/machines/cu430hx/1004DK0K.BI1", + "roms/machines/cu430hx/1004DK0K.BI2", "roms/machines/cu430hx/1004DK0K.BI3", + "roms/machines/cu430hx/1004DK0K.RCV", "" } }, { .name = "Intel AMIBIOS - Revision 1.00.06.DK0", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3", From 0f1e6f2196835c070d1bd46592150bf041f96753 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 11 Sep 2025 00:59:03 +0700 Subject: [PATCH 054/138] Machine adjustments --- src/machine/machine_table.c | 364 ++++++++++++++++++------------------ 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 20baadfcf..758f07993 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -1937,7 +1937,7 @@ const machine_t machines[] = { .ram = { .min = 64, .max = 1024, - .step = 128 + .step = 64 }, .nvrmask = 127, .jumpered_ecp_dma = 0, @@ -3831,7 +3831,7 @@ const machine_t machines[] = { /* AMI BIOS for a chipset-less machine, most likely has AMI 'F' KBC firmware. */ { .name = "[ISA] Trangg Bow Unknown 286", - .internal_name = "ibmatami", + .internal_name = "tbunk286", .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_tbunk286_init, @@ -3853,8 +3853,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 512, - .step = 256 + .max = 1024, + .step = 128 }, .nvrmask = 63, .jumpered_ecp_dma = 0, @@ -3916,49 +3916,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* has an Award-branded KBC controller */ - { - .name = "[NEAT] Hyundai Super-286C", - .internal_name = "super286c", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_super286c_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 1024, - .step = 128 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_AWARD | 0x00424600, - .kbc_p1 = 0x000004f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC firmware. */ { @@ -4181,6 +4138,50 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has Phoenix MultiKey/42 KBC firmware. */ + { + .name = "[NEAT] Arche AMA-2010", + .internal_name = "px286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_px286_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 8192, + .step = 128 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + /* The version number is a guess - we have no probe of this machine's controller. */ + .kbc_params = KBC_VEN_PHOENIX | 0x00010500, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Most likely has Chips & Technologies KBC firmware. */ { .name = "[NEAT] Atari PC 4", @@ -4269,6 +4270,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* has an Award-branded KBC controller */ + { + .name = "[NEAT] Hyundai Super-286C", + .internal_name = "super286c", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_NEAT, + .init = machine_at_super286c_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 1024, + .step = 128 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_AWARD | 0x00424600, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has NCR KBC firmware. */ { .name = "[NEAT] NCR 3302", @@ -4313,50 +4357,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has Phoenix MultiKey/42 KBC firmware. */ - { - .name = "[NEAT] Arche AMA-2010", - .internal_name = "px286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_px286_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 8192, - .step = 128 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - /* The version number is a guess - we have no probe of this machine's controller. */ - .kbc_params = KBC_VEN_PHOENIX | 0x00010500, - .kbc_p1 = 0x000004f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has the VLSI 82C113 with on-chip KBC. */ { .name = "[SCAMP] Amstrad PC7286", @@ -4867,9 +4867,9 @@ const machine_t machines[] = { .bus_flags = MACHINE_AT, .flags = MACHINE_IDE, .ram = { - .min = 1024, + .min = 512, .max = 4096, - .step = 1024 + .step = 128 }, .nvrmask = 127, .jumpered_ecp_dma = 0, @@ -8742,7 +8742,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE | MACHINE_APM, /* Machine has internal SCSI: Adaptec AIC-6360 */ .ram = { .min = 1024, - .max = 32768, + .max = 65536, .step = 1024 }, .nvrmask = 127, @@ -9480,94 +9480,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has IBM PS/2 Type 1 KBC firmware. */ - { - .name = "[OPTi 802G] IBM PC 330 (type 6573)", - .internal_name = "pc330_6573", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_pc330_6573_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3_PC330, - .block = CPU_BLOCK_NONE, - .min_bus = 25000000, - .max_bus = 33333333, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 2.0, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &pc330_6573_device, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5430_onboard_vlb_device, - .snd_device = NULL, - .net_device = NULL - }, - /* has a Phoenix PLCC Multikey copyrighted 1993, version unknown. */ - { - .name = "[OPTi 895] Packard Bell PB450", - .internal_name = "pb450", - .type = MACHINE_TYPE_486_S3_PCI, - .chipset = MACHINE_CHIPSET_OPTI_895_802G, - .init = machine_at_pb450_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET3, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2_PCI, - .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_VIDEO, - .ram = { - .min = 1024, - .max = 65536, - .step = 1024 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess. */ - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &pb450_device, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &gd5428_vlb_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, /* This has an AMIKey-2, which is an updated version of type 'H'. */ { .name = "[i420EX] Advanced Integration Research 486PI", @@ -10057,6 +9969,94 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has IBM PS/2 Type 1 KBC firmware. */ + { + .name = "[OPTi 802G] IBM PC 330 (type 6573)", + .internal_name = "pc330_6573", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_pc330_6573_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3_PC330, + .block = CPU_BLOCK_NONE, + .min_bus = 25000000, + .max_bus = 33333333, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 2.0, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pc330_6573_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5430_onboard_vlb_device, + .snd_device = NULL, + .net_device = NULL + }, + /* has a Phoenix PLCC Multikey copyrighted 1993, version unknown. */ + { + .name = "[OPTi 895] Packard Bell PB450", + .internal_name = "pb450", + .type = MACHINE_TYPE_486_S3_PCI, + .chipset = MACHINE_CHIPSET_OPTI_895_802G, + .init = machine_at_pb450_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET3, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2_PCI, + .flags = MACHINE_SUPER_IO | MACHINE_IDE_DUAL | MACHINE_VIDEO, + .ram = { + .min = 1024, + .max = 65536, + .step = 1024 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_PHOENIX | 0x00021400, /* Guess. */ + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &pb450_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &gd5428_vlb_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, /* Has Acer KBC firmware. */ { .name = "[SiS 496] Acer P3", From 3824b2b7820a78e39d80bd1eef3bcbe4d70afbc2 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 11 Sep 2025 01:38:22 +0700 Subject: [PATCH 055/138] Revert Trangg Bow Unknown 286 changes + overhaul --- src/machine/machine_table.c | 1127 ++++++++++++++++++----------------- 1 file changed, 564 insertions(+), 563 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 758f07993..3f493eef9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2429,49 +2429,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - { - .name = "[8086] Amstrad PC20(0)", - .internal_name = "pc200", - .type = MACHINE_TYPE_8086, - .chipset = MACHINE_CHIPSET_PROPRIETARY, - .init = machine_pc200_init, - .p1_handler = NULL, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_8086, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 10000000, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PC, - .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MOUSE, - .ram = { - .min = 512, - .max = 640, - .step = 128 - }, - .nvrmask = 63, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL /* TODO: No specific kbd_device yet */, - .kbc_params = 0x00000000, - .kbc_p1 = 0xff, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &vid_200_device, - .snd_device = NULL, - .net_device = NULL - }, { .name = "[8086] Amstrad PC5086", .internal_name = "pc5086", @@ -2515,6 +2472,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + { + .name = "[8086] Amstrad PC20(0)", + .internal_name = "pc200", + .type = MACHINE_TYPE_8086, + .chipset = MACHINE_CHIPSET_PROPRIETARY, + .init = machine_pc200_init, + .p1_handler = NULL, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_8086, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 10000000, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PC, + .flags = MACHINE_VIDEO | MACHINE_KEYBOARD | MACHINE_MOUSE, + .ram = { + .min = 512, + .max = 640, + .step = 128 + }, + .nvrmask = 63, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL /* TODO: No specific kbd_device yet */, + .kbc_params = 0x00000000, + .kbc_p1 = 0xff, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &vid_200_device, + .snd_device = NULL, + .net_device = NULL + }, { .name = "[8086] Amstrad PPC512/640", .internal_name = "ppc512", @@ -3519,6 +3519,51 @@ const machine_t machines[] = { .net_device = NULL }, /* Has IBM AT KBC firmware. */ + /* To configure the BIOS, use PB_2330a_diag.IMA from MS-DOS 3.30 Packard Bell OEM, GSETUP might work too*/ + { + .name = "[ISA] Packard Bell PB286", + .internal_name = "pb286", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_pb286_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 256, + .max = 1024, + .step = 128 + }, + .nvrmask = 63, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = 0x00000000, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has IBM AT KBC firmware. */ { .name = "[ISA] Phoenix AT clone", .internal_name = "ibmatpx", @@ -3606,51 +3651,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has IBM AT KBC firmware. */ - /* To configure the BIOS, use PB_2330a_diag.IMA from MS-DOS 3.30 Packard Bell OEM, GSETUP might work too*/ - { - .name = "[ISA] Packard Bell PB286", - .internal_name = "pb286", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_pb286_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 256, - .max = 1024, - .step = 128 - }, - .nvrmask = 63, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = 0x00000000, - .kbc_p1 = 0x000004f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has unknown KBC firmware. */ { .name = "[ISA] Sanyo MBC-17PLUS", @@ -3831,7 +3831,7 @@ const machine_t machines[] = { /* AMI BIOS for a chipset-less machine, most likely has AMI 'F' KBC firmware. */ { .name = "[ISA] Trangg Bow Unknown 286", - .internal_name = "tbunk286", + .internal_name = "ibmatami", .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, .init = machine_at_tbunk286_init, @@ -3853,8 +3853,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 1024, - .step = 128 + .max = 512, + .step = 256 }, .nvrmask = 63, .jumpered_ecp_dma = 0, @@ -5155,50 +5155,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* This has a Holtek keyboard controller which clones AMI 'H'. */ - { - .name = "[ALi M1217] Acrosser AR-B1374", - .internal_name = "arb1374", - .type = MACHINE_TYPE_386SX, - .chipset = MACHINE_CHIPSET_ALI_M1217, - .init = machine_at_arb1374_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386SX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_PS2, - .flags = MACHINE_IDE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_HOLTEK | 0x00004800, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has the AMIKey-2 KBC - that's actually a guess since we do not currently have a picture of the motherboard. */ { @@ -5244,6 +5200,50 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* This has a Holtek keyboard controller which clones AMI 'H'. */ + { + .name = "[ALi M1217] Acrosser AR-B1374", + .internal_name = "arb1374", + .type = MACHINE_TYPE_386SX, + .chipset = MACHINE_CHIPSET_ALI_M1217, + .init = machine_at_arb1374_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386SX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_PS2, + .flags = MACHINE_IDE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_HOLTEK | 0x00004800, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a VIA VT82C42N KBC. */ { .name = "[ALi M1217] Flytech A36", @@ -6449,6 +6449,47 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Lance LT38C41 that clones an AMIKEY ('F'). */ + { + .name = "[ALi M1429] ECS Panda 386V", + .internal_name = "ecs386v", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_ALI_M1429, + .init = machine_at_ecs386v_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0, + }, + .bus_flags = MACHINE_VLB, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 1024, + .max = 32768, + .step = 1024, + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, /* TODO: Lance LT38C41. */ + .kbc_params = KBC_VEN_AMI | 0x00004600, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has an AMI Keyboard BIOS PLUS KBC firmware ('8'). */ { .name = "[C&T 386/AT] ECS 386/32", @@ -6582,47 +6623,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a Lance LT38C41 that clones an AMIKEY ('F'). */ - { - .name = "[ALi M1429] ECS Panda 386V", - .internal_name = "ecs386v", - .type = MACHINE_TYPE_386DX, - .chipset = MACHINE_CHIPSET_ALI_M1429, - .init = machine_at_ecs386v_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_386DX, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0, - }, - .bus_flags = MACHINE_VLB, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 1024, - .max = 32768, - .step = 1024, - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, /* TODO: Lance LT38C41. */ - .kbc_params = KBC_VEN_AMI | 0x00004600, - .kbc_p1 = 0x000004f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has AMIKey 'F' KBC firmware. */ { .name = "[OPTi 391] DataExpert 386WB", @@ -13123,7 +13123,7 @@ const machine_t machines[] = { .block = CPU_BLOCK_NONE, .min_bus = 50000000, .max_bus = 66666667, - .min_voltage = 2500, + .min_voltage = 3380, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 3.0 @@ -13737,6 +13737,140 @@ const machine_t machines[] = { }, /* Socket 7 (Dual Voltage) machines */ + /* ALi ALADDiN IV+ */ + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN IV+] Biostar M5ATA", + .internal_name = "m5ata", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, + .init = machine_at_m5ata_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 66666667, + .min_voltage = 2100, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 4.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &m5ata_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN IV+] MSI MS-5164", + .internal_name = "ms5164", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, + .init = machine_at_ms5164_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 83333333, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the ALi M1543 southbridge with on-chip KBC. */ + { + .name = "[ALi ALADDiN IV+] PC Chips M560", + .internal_name = "m560", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, + .init = machine_at_m560_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 83333333, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* 430HX */ /* Has a SM(S)C FDC37C935 Super I/O chip with on-chip KBC with Phoenix MultiKey/42 (version 1.38) KBC firmware. */ @@ -15418,145 +15552,6 @@ const machine_t machines[] = { .net_device = NULL }, - /* Apollo VPX */ - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA VPX] FIC VA-502", - .internal_name = "ficva502", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_VPX, - .init = machine_at_ficva502_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2800, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 524288, - .step = 8192 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - - /* Apollo VP3 */ - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA VP3] FIC PA-2012", - .internal_name = "ficpa2012", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, - .init = machine_at_ficpa2012_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 55000000, - .max_bus = 75000000, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA - VT82C42N. */ - { - .name = "[VIA VP3] PC Partner VIA809DS", - .internal_name = "via809ds", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, - .init = machine_at_via809ds_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1048576, - .step = 8192 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* SiS 5571 */ /* Has the SiS 5571 chipset with on-chip KBC. */ { @@ -15827,14 +15822,15 @@ const machine_t machines[] = { .net_device = NULL }, - /* ALi ALADDiN IV+ */ - /* Has the ALi M1543 southbridge with on-chip KBC. */ + /* Apollo VPX */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { - .name = "[ALi ALADDiN IV+] Biostar M5ATA", - .internal_name = "m5ata", + .name = "[VIA VPX] FIC VA-502", + .internal_name = "ficva502", .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, - .init = machine_at_m5ata_init, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_VPX, + .init = machine_at_ficva502_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -15842,53 +15838,9 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 66666667, - .min_voltage = 2100, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 4.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = &m5ata_device, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has the ALi M1543 southbridge with on-chip KBC. */ - { - .name = "[ALi ALADDiN IV+] MSI MS-5164", - .internal_name = "ms5164", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, - .init = machine_at_ms5164_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 83333333, - .min_voltage = 2100, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2800, .max_voltage = 3520, .min_multi = 1.5, .max_multi = 3.0 @@ -15897,10 +15849,10 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 1048576, + .max = 524288, .step = 8192 }, - .nvrmask = 255, + .nvrmask = 127, .jumpered_ecp_dma = 0, .default_jumpered_ecp_dma = -1, .kbc_device = NULL, @@ -15916,13 +15868,61 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has the ALi M1543 southbridge with on-chip KBC. */ + + /* Apollo VP3 */ + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ { - .name = "[ALi ALADDiN IV+] PC Chips M560", - .internal_name = "m560", + .name = "[VIA VP3] FIC PA-2012", + .internal_name = "ficpa2012", .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, - .init = machine_at_m560_init, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, + .init = machine_at_ficpa2012_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 55000000, + .max_bus = 75000000, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1048576, + .step = 8192 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA + VT82C42N. */ + { + .name = "[VIA VP3] PC Partner VIA809DS", + .internal_name = "via809ds", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, + .init = machine_at_via809ds_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -15931,20 +15931,20 @@ const machine_t machines[] = { .package = CPU_PKG_SOCKET5_7, .block = CPU_BLOCK_NONE, .min_bus = 50000000, - .max_bus = 83333333, + .max_bus = 75000000, .min_voltage = 2100, .max_voltage = 3520, .min_multi = 1.5, - .max_multi = 3.0 + .max_multi = 5.5 }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, + .max = 1048576, .step = 8192 }, - .nvrmask = 255, + .nvrmask = 127, .jumpered_ecp_dma = 0, .default_jumpered_ecp_dma = -1, .kbc_device = NULL, @@ -16185,6 +16185,52 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS 5591 */ + /* Has the SiS 5591 chipset with on-chip KBC. */ + { + .name = "[SiS 5591] Gigabyte GA-5SG100", + .internal_name = "5sg100", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_SIS_5591, + .init = machine_at_5sg100_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 60000000, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* Apollo MVP3 */ /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA VT82C42N. */ @@ -16412,52 +16458,6 @@ const machine_t machines[] = { .net_device = NULL }, - /* SiS 5591 */ - /* Has the SiS 5591 chipset with on-chip KBC. */ - { - .name = "[SiS 5591] Gigabyte GA-5SG100", - .internal_name = "5sg100", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_SIS_5591, - .init = machine_at_5sg100_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 60000000, - .max_bus = 100000000, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Socket 8 machines */ /* 450KX */ /* This has an AMIKey-2, which is type 'H'. */ @@ -17951,6 +17951,96 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS (5)600 */ + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] Freetech/Flexus P6F99", + .internal_name = "p6f99", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_p6f99_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = &es1373_onboard_device, + .net_device = NULL + }, + /* Has the SiS (5)600 chipset with on-chip KBC. */ + { + .name = "[SiS 5600] PC Chips M747", + .internal_name = "m747", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_m747_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1300, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: SiS 6326 and internal sound: C-Media CMI8330 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* SMSC VictoryBX-66 */ /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ @@ -18180,96 +18270,6 @@ const machine_t machines[] = { .net_device = NULL }, - /* SiS (5)600 */ - /* Has the SiS (5)600 chipset with on-chip KBC. */ - { - .name = "[SiS 5600] Freetech/Flexus P6F99", - .internal_name = "p6f99", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_SIS_5600, - .init = machine_at_p6f99_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_SOUND | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal sound: Ensoniq ES1373 */ - .ram = { - .min = 8192, - .max = 1572864, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = &es1373_onboard_device, - .net_device = NULL - }, - /* Has the SiS (5)600 chipset with on-chip KBC. */ - { - .name = "[SiS 5600] PC Chips M747", - .internal_name = "m747", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_SIS_5600, - .init = machine_at_m747_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1300, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_GAMEPORT | MACHINE_USB, /* Machine has internal video: SiS 6326 and internal sound: C-Media CMI8330 */ - .ram = { - .min = 8192, - .max = 1572864, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Slot 1/2 machines */ /* 440GX */ /* Has a National Semiconductors PC87309 Super I/O chip with on-chip KBC @@ -18783,6 +18783,53 @@ const machine_t machines[] = { .net_device = NULL }, + /* SiS (5)600 */ + /* Has the SiS 600 chipset, which is a re-brand of the 5600, with + on-chip KBC. */ + { + .name = "[SiS 600] Soyo SY-7SBB", + .internal_name = "7sbb", + .type = MACHINE_TYPE_SOCKET370, + .chipset = MACHINE_CHIPSET_SIS_5600, + .init = machine_at_7sbb_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET370, + .block = CPU_BLOCK(CPU_CYRIX3S), + .min_bus = 60000000, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + /* SMSC VictoryBX-66 */ /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ @@ -19056,52 +19103,6 @@ const machine_t machines[] = { .snd_device = &cmi8738_onboard_device, .net_device = NULL }, - /* SiS (5)600 */ - /* Has the SiS 600 chipset, which is a re-brand of the 5600, with - on-chip KBC. */ - { - .name = "[SiS 600] Soyo SY-7SBB", - .internal_name = "7sbb", - .type = MACHINE_TYPE_SOCKET370, - .chipset = MACHINE_CHIPSET_SIS_5600, - .init = machine_at_7sbb_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET370, - .block = CPU_BLOCK(CPU_CYRIX3S), - .min_bus = 60000000, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 1572864, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Miscellaneous/Fake/Hypervisor machines */ /* Has a Winbond W83977F Super I/O chip with on-chip KBC with AMIKey-2 KBC From 015e683059d916bea8224e2ff5038a6c89b14e6e Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 11 Sep 2025 01:47:01 +0700 Subject: [PATCH 056/138] Forgotten change Change the name for Dell 466/NP for one of its specifications (425s, 433s, 433d, 450d, and 466d) --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3f493eef9..7ece9259f 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8317,7 +8317,7 @@ const machine_t machines[] = { }, /* Uses a ???? KBC. */ { - .name = "[SiS 461] Dell 466/NP", + .name = "[SiS 461] Dell 4xx/NP", .internal_name = "dell466np", .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_461, From f7323ddb58c2110a074f5019d5816df729e42174 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Thu, 11 Sep 2025 03:56:35 +0700 Subject: [PATCH 057/138] Added 'system' to the Dell 4xx/NP name --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 7ece9259f..d26f5e396 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -8317,7 +8317,7 @@ const machine_t machines[] = { }, /* Uses a ???? KBC. */ { - .name = "[SiS 461] Dell 4xx/NP", + .name = "[SiS 461] Dell System 4xx/NP", .internal_name = "dell466np", .type = MACHINE_TYPE_486_S2, .chipset = MACHINE_CHIPSET_SIS_461, From 91413a84576dd4876e46fddbb76e6ada6e0c094a Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sun, 3 Aug 2025 17:36:07 +0500 Subject: [PATCH 058/138] GUS gameport work Classic: gameport toggleable by jumper/config option (pre-rev 3.4), disabled by default MAX: gameport toggleable by software register (post-rev 3.4), enabled by default Disable access to rev 3.4+ registers on Classic --- src/sound/snd_gus.c | 95 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 21 deletions(-) diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 80ce6781d..ff2bfdd8f 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -13,6 +13,7 @@ #include <86box/io.h> #include <86box/midi.h> #include <86box/nmi.h> +#include <86box/gameport.h> #include <86box/pic.h> #include <86box/sound.h> #include "cpu.h" @@ -120,7 +121,9 @@ typedef struct gus_t { uint8_t sb_ctrl; int sb_nmi; + uint8_t joy_trim; uint8_t reg_ctrl; + uint8_t jumper; uint8_t ad_status; uint8_t ad_data; @@ -143,6 +146,8 @@ typedef struct gus_t { uint8_t usrr; + void *gameport; + uint8_t max_ctrl; ad1848_t ad1848; @@ -159,6 +164,9 @@ int gusfreqs[] = { double vol16bit[4096]; +void gus_write(uint16_t addr, uint8_t val, void *priv); +uint8_t gus_read(uint16_t addr, void *priv); + void gus_update_int_status(gus_t *gus) { @@ -537,6 +545,10 @@ gus_write(uint16_t addr, uint8_t val, void *priv) gus->t2on = 1; break; + case 0x4B: /*Joystick trim DAC*/ + gus->joy_trim = val; + break; + case 0x4c: /*Reset*/ gus->reset = val; break; @@ -634,9 +646,23 @@ gus_write(uint16_t addr, uint8_t val, void *priv) gus->gp2_addr = val; break; case 5: - gus->usrr = 0; + if (gus->type > GUS_CLASSIC) + gus->usrr = 0; break; case 6: + if (gus->type > GUS_CLASSIC) { + if (!(val & 0x2) && (gus->jumper & 0x2)) + io_removehandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + else if ((val & 0x2) && !(gus->jumper & 0x2)) + io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + + if (!(val & 0x4) && (gus->jumper & 0x4)) + gameport_remap(gus->gameport, 0x0); + else if ((val & 0x4) && !(gus->jumper & 0x4)) + gameport_remap(gus->gameport, 0x201); + + gus->jumper = val; + } break; default: @@ -672,7 +698,8 @@ gus_write(uint16_t addr, uint8_t val, void *priv) gus->sb_2xe = val; break; case 0x20f: - gus->reg_ctrl = val; + if (gus->type > GUS_CLASSIC) + gus->reg_ctrl = val; break; case 0x306: case 0x706: @@ -746,10 +773,10 @@ gus_read(uint16_t addr, void *priv) return val; case 0x20F: - if (gus->type == GUS_MAX) - val = 0x02; + if (gus->type > GUS_CLASSIC) + val = gus->jumper; else - val = 0x00; + val = 0xff; break; case 0x302: @@ -842,6 +869,9 @@ gus_read(uint16_t addr, void *priv) case 0x49: /*Sampling control*/ return 0; + case 0x4B: /*Joystick trim DAC*/ + return gus->joy_trim; + case 0x00: case 0x01: case 0x02: @@ -884,22 +914,24 @@ gus_read(uint16_t addr, void *priv) return 0; case 0x20b: - switch (gus->reg_ctrl & 0x07) { - case 1: - val = gus->gp1; - break; - case 2: - val = gus->gp2; - break; - case 3: - val = gus->gp1_addr; - break; - case 4: - val = gus->gp2_addr; - break; + if (gus->type > GUS_CLASSIC) { + switch (gus->reg_ctrl & 0x07) { + case 1: + val = gus->gp1; + break; + case 2: + val = gus->gp2; + break; + case 3: + val = gus->gp1_addr; + break; + case 4: + val = gus->gp2_addr; + break; - default: - break; + default: + break; + } } break; @@ -1292,6 +1324,7 @@ gus_reset(void *priv) gus->sb_ctrl = 0; gus->sb_nmi = 0; + gus->joy_trim = 29; gus->reg_ctrl = 0; gus->ad_status = 0; @@ -1355,12 +1388,21 @@ gus_init(UNUSED(const device_t *info)) gus->type = info->local; + gus->jumper = 0x06; + gus->base = device_get_config_hex16("base"); io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); - io_sethandler(0x0100 + gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + io_sethandler(0x0102 + gus->base, 0x000e, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + if (gus->type == GUS_CLASSIC && device_get_config_int("gameport")) + gus->gameport = gameport_add(&gameport_201_device); + else { + gus->gameport = gameport_add(&gameport_pnp_1io_device); + gameport_remap(gus->gameport, 0x201); + } if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); @@ -1442,6 +1484,17 @@ static const device_config_t gus_config[] = { }, .bios = { { 0 } } }, + { + .name = "gameport", + .description = "Enable Game port", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, { .name = "receive_input", .description = "Receive MIDI input", From 7f7461620d780eb5ef6f78fc91b6ae5856ede782 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Sep 2025 05:24:07 +0500 Subject: [PATCH 059/138] GUS: Correct minimum RAM amount for GUS MAX --- src/sound/snd_gus.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index ff2bfdd8f..5e0043ad6 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1510,6 +1510,57 @@ static const device_config_t gus_config[] = { // clang-format off }; +static const device_config_t gus_max_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "210H", .value = 0x210 }, + { .description = "220H", .value = 0x220 }, + { .description = "230H", .value = 0x230 }, + { .description = "240H", .value = 0x240 }, + { .description = "250H", .value = 0x250 }, + { .description = "260H", .value = 0x260 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "gus_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 1 }, + { .description = "1 MB", .value = 2 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + const device_t gus_device = { .name = "Gravis UltraSound", .internal_name = "gus", @@ -1535,5 +1586,5 @@ const device_t gus_max_device = { .available = NULL, .speed_changed = gus_speed_changed, .force_redraw = NULL, - .config = gus_config + .config = gus_max_config }; From eec9b52151d5af6e99536dd7f489e9c979f807e1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Mon, 1 Sep 2025 05:33:02 +0500 Subject: [PATCH 060/138] GUS: Add the UltraSound ACE --- src/include/86box/sound.h | 3 +- src/qt/languages/86box.pot | 3 ++ src/qt/languages/cs-CZ.po | 3 ++ src/qt/languages/de-DE.po | 3 ++ src/qt/languages/es-ES.po | 3 ++ src/qt/languages/fi-FI.po | 3 ++ src/qt/languages/fr-FR.po | 3 ++ src/qt/languages/hr-HR.po | 3 ++ src/qt/languages/it-IT.po | 3 ++ src/qt/languages/ja-JP.po | 3 ++ src/qt/languages/ko-KR.po | 3 ++ src/qt/languages/nb-NO.po | 3 ++ src/qt/languages/nl-NL.po | 3 ++ src/qt/languages/pl-PL.po | 3 ++ src/qt/languages/pt-BR.po | 3 ++ src/qt/languages/pt-PT.po | 3 ++ src/qt/languages/ru-RU.po | 3 ++ src/qt/languages/sk-SK.po | 3 ++ src/qt/languages/sl-SI.po | 3 ++ src/qt/languages/sv-SE.po | 3 ++ src/qt/languages/tr-TR.po | 3 ++ src/qt/languages/uk-UA.po | 3 ++ src/qt/languages/vi-VN.po | 3 ++ src/qt/languages/zh-CN.po | 3 ++ src/qt/languages/zh-TW.po | 3 ++ src/sound/snd_gus.c | 104 ++++++++++++++++++++++++++++++++----- src/sound/sound.c | 1 + 27 files changed, 165 insertions(+), 15 deletions(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 5f91ec9d0..8c223cff9 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -203,9 +203,10 @@ extern const device_t es1373_onboard_device; extern const device_t ct5880_device; extern const device_t ct5880_onboard_device; -/* Gravis UltraSound and UltraSound Max */ +/* Gravis UltraSound family */ extern const device_t gus_device; extern const device_t gus_max_device; +extern const device_t gus_ace_device; /* IBM PS/1 Audio Card */ extern const device_t ps1snd_device; diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index a65578eae..df6f01f3c 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -2136,6 +2136,9 @@ msgstr "" msgid "Enable Game port" msgstr "" +msgid "Enable Adlib ports" +msgstr "" + msgid "SID Model" msgstr "" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index ae265593c..6cef7611c 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -2136,6 +2136,9 @@ msgstr "Nízký DMA kanál" msgid "Enable Game port" msgstr "Povolit herní port" +msgid "Enable Adlib ports" +msgstr "Povolit porty Adlib" + msgid "SID Model" msgstr "Model SID" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 4385811c0..3b92f7ec3 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -2136,6 +2136,9 @@ msgstr "Niedrige DMA" msgid "Enable Game port" msgstr "Game-Port einschalten" +msgid "Enable Adlib ports" +msgstr "Adlib-Ports einschalten" + msgid "SID Model" msgstr "SID-Modell" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index b3d8835cf..46bd759fe 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -2136,6 +2136,9 @@ msgstr "DMA bajo" msgid "Enable Game port" msgstr "Habilitar puerto de juegos" +msgid "Enable Adlib ports" +msgstr "Habilitar puertos Adlib" + msgid "SID Model" msgstr "Modelo de SID" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 475d94b7b..dc3cae0cf 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -2136,6 +2136,9 @@ msgstr "Matala DMA" msgid "Enable Game port" msgstr "Peliportti" +msgid "Enable Adlib ports" +msgstr "Adlib-portit" + msgid "SID Model" msgstr "SID-malli" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 3f28b4af8..c31b4c8a6 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -2136,6 +2136,9 @@ msgstr "DMA bas" msgid "Enable Game port" msgstr "Activer le port de jeu" +msgid "Enable Adlib ports" +msgstr "Activer les ports Adlib" + msgid "SID Model" msgstr "Modèle SID" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 4996db404..4f2d8ee93 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -2136,6 +2136,9 @@ msgstr "Niski DMA" msgid "Enable Game port" msgstr "Omogoći vrata za igru" +msgid "Enable Adlib ports" +msgstr "Omogući Adlib portove" + msgid "SID Model" msgstr "Model SID-a" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index f0806bf7b..4c0a6722a 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -2136,6 +2136,9 @@ msgstr "DMA basso" msgid "Enable Game port" msgstr "Abilita la porta giochi" +msgid "Enable Adlib ports" +msgstr "Abilita porte Adlib" + msgid "SID Model" msgstr "Modello SID" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index be01430f9..2fb7da257 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -2136,6 +2136,9 @@ msgstr "低DMA" msgid "Enable Game port" msgstr "ゲームポートを有効にする" +msgid "Enable Adlib ports" +msgstr "Adlibポートを有効にする" + msgid "SID Model" msgstr "SIDモデル" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 14da0ec8b..a9fa55f5b 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -2136,6 +2136,9 @@ msgstr "낮은 DMA" msgid "Enable Game port" msgstr "게임 포트 사용" +msgid "Enable Adlib ports" +msgstr "Adlib 포트 활성화" + msgid "SID Model" msgstr "SID 모델" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index 8d9f97521..53115d4b1 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -2136,6 +2136,9 @@ msgstr "Lav DMA" msgid "Enable Game port" msgstr "Aktiver spillport" +msgid "Enable Adlib ports" +msgstr "Aktiver Adlib-porter" + msgid "SID Model" msgstr "SID-modell" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index d28a72651..acc3526ec 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -2136,6 +2136,9 @@ msgstr "Lage DMA" msgid "Enable Game port" msgstr "Game-poort inschakelen" +msgid "Enable Adlib ports" +msgstr "Adlib-poorten inschakelen" + msgid "SID Model" msgstr "SID-model" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 2a0cde697..81bedb546 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -2136,6 +2136,9 @@ msgstr "Niski poziom DMA" msgid "Enable Game port" msgstr "Włącz port gier" +msgid "Enable Adlib ports" +msgstr "Włącz porty Adlib" + msgid "SID Model" msgstr "Model SID" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 63a17871b..211d39f16 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -2136,6 +2136,9 @@ msgstr "DMA baixo" msgid "Enable Game port" msgstr "Ativar a porta do jogo" +msgid "Enable Adlib ports" +msgstr "Ativar portas Adlib" + msgid "SID Model" msgstr "Modelo do SID" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 4c7866f41..bd7894f6e 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -2136,6 +2136,9 @@ msgstr "DMA baixo" msgid "Enable Game port" msgstr "Ativar a porta de jogos" +msgid "Enable Adlib ports" +msgstr "Ativar portas Adlib" + msgid "SID Model" msgstr "Modelo do SID" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 904757d74..6535b6603 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -2136,6 +2136,9 @@ msgstr "Низкий DMA" msgid "Enable Game port" msgstr "Включить игровой порт" +msgid "Enable Adlib ports" +msgstr "Включить порты Adlib" + msgid "SID Model" msgstr "Модель SID" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 3a5e3b863..20f86033c 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -2136,6 +2136,9 @@ msgstr "Nízka hodnota DMA" msgid "Enable Game port" msgstr "Povolenie herného portu" +msgid "Enable Adlib ports" +msgstr "Povoliť porty Adlib" + msgid "SID Model" msgstr "Model SID" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index c23024a33..0813e3d83 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -2136,6 +2136,9 @@ msgstr "Nizki DMA" msgid "Enable Game port" msgstr "Omogočanje igralnih vrat" +msgid "Enable Adlib ports" +msgstr "Omogoči vrata Adlib" + msgid "SID Model" msgstr "Model SID-a" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index 58ead9405..e3db6d3b7 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -2136,6 +2136,9 @@ msgstr "Låg DMA" msgid "Enable Game port" msgstr "Aktivera spelport" +msgid "Enable Adlib ports" +msgstr "Aktivera Adlib-portar" + msgid "SID Model" msgstr "SID-modell" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 538cc7af6..65eb47152 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -2136,6 +2136,9 @@ msgstr "Düşük DMA" msgid "Enable Game port" msgstr "Gameport'ı etkinleştir" +msgid "Enable Adlib ports" +msgstr "Adlib bağlantı noktalarını etkinleştir" + msgid "SID Model" msgstr "SID Modeli" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index c079fc141..79f5763c3 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -2136,6 +2136,9 @@ msgstr "Низький рівень DMA" msgid "Enable Game port" msgstr "Увімкнути ігровий порт" +msgid "Enable Adlib ports" +msgstr "Увімкнути порти Adlib" + msgid "SID Model" msgstr "Модель SID" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index 0190aee4c..f316c54c2 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -2136,6 +2136,9 @@ msgstr "DMA thấp" msgid "Enable Game port" msgstr "Bật cổng trò chơi" +msgid "Enable Adlib ports" +msgstr "Bật cổng Adlib" + msgid "SID Model" msgstr "Mẫu SID" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 7f44fe4fc..31a34da90 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -2136,6 +2136,9 @@ msgstr "低 DMA" msgid "Enable Game port" msgstr "启用游戏端口" +msgid "Enable Adlib ports" +msgstr "启用 Adlib 端口" + msgid "SID Model" msgstr "SID 芯片型号" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 21a984ebd..7dcb3638f 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -2136,6 +2136,9 @@ msgstr "低 DMA" msgid "Enable Game port" msgstr "啟用遊戲埠" +msgid "Enable Adlib ports" +msgstr "啟用 Adlib 連接埠" + msgid "SID Model" msgstr "SID 型號" diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 5e0043ad6..cc585c8db 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -46,6 +46,7 @@ enum { enum { GUS_CLASSIC = 0, GUS_MAX = 1, + GUS_ACE = 2, }; typedef struct gus_t { @@ -651,15 +652,17 @@ gus_write(uint16_t addr, uint8_t val, void *priv) break; case 6: if (gus->type > GUS_CLASSIC) { - if (!(val & 0x2) && (gus->jumper & 0x2)) - io_removehandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); - else if ((val & 0x2) && !(gus->jumper & 0x2)) - io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + if (gus->type != GUS_ACE) { + if (!(val & 0x2) && (gus->jumper & 0x2)) + io_removehandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + else if ((val & 0x2) && !(gus->jumper & 0x2)) + io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); - if (!(val & 0x4) && (gus->jumper & 0x4)) - gameport_remap(gus->gameport, 0x0); - else if ((val & 0x4) && !(gus->jumper & 0x4)) - gameport_remap(gus->gameport, 0x201); + if (!(val & 0x4) && (gus->jumper & 0x4)) + gameport_remap(gus->gameport, 0x0); + else if ((val & 0x4) && !(gus->jumper & 0x4)) + gameport_remap(gus->gameport, 0x201); + } gus->jumper = val; } @@ -899,6 +902,8 @@ gus_read(uint16_t addr, void *priv) case 0x706: if (gus->type == GUS_MAX) val = 0x0a; /* GUS MAX */ + else if (gus->type == GUS_ACE) + val = 0x30; /* GUS ACE */ else val = 0xff; /*Pre 3.7 - no mixer*/ break; @@ -943,8 +948,11 @@ gus_read(uint16_t addr, void *priv) case 0x20e: return gus->sb_2xe; - case 0x208: case 0x388: + if ((gus->type == GUS_ACE) && !device_get_config_int("adlib_ports")) + break; + fallthrough; + case 0x208: if (gus->tctrl & GUS_TIMER_CTRL_AUTO) val = gus->sb_2xa; else { @@ -959,10 +967,12 @@ gus_read(uint16_t addr, void *priv) #ifdef OLD_NMI_BEHAVIOR nmi = 0; #endif /* OLD_NMI_BEHAVIOR */ - fallthrough; - case 0x389: val = gus->ad_data; break; + case 0x389: + if ((gus->type != GUS_ACE) || device_get_config_int("adlib_ports")) + val = gus->ad_data; + break; case 0x20A: val = gus->adcommand; @@ -1393,13 +1403,14 @@ gus_init(UNUSED(const device_t *info)) gus->base = device_get_config_hex16("base"); io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); - io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); + if (gus->type != GUS_ACE) + io_sethandler(0x0100 + gus->base, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0102 + gus->base, 0x000e, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0506 + gus->base, 0x0001, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); io_sethandler(0x0388, 0x0002, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); if (gus->type == GUS_CLASSIC && device_get_config_int("gameport")) gus->gameport = gameport_add(&gameport_201_device); - else { + else if (gus->type != GUS_ACE) { gus->gameport = gameport_add(&gameport_pnp_1io_device); gameport_remap(gus->gameport, 0x201); } @@ -1418,7 +1429,7 @@ gus_init(UNUSED(const device_t *info)) sound_add_handler(gus_get_buffer, gus); - if (device_get_config_int("receive_input")) + if ((gus->type != GUS_ACE) && (device_get_config_int("receive_input"))) midi_in_handler(1, gus_input_msg, gus_input_sysex, gus); return gus; @@ -1561,6 +1572,57 @@ static const device_config_t gus_max_config[] = { // clang-format off }; +static const device_config_t gus_ace_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x260, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "210H", .value = 0x210 }, + { .description = "220H", .value = 0x220 }, + { .description = "230H", .value = 0x230 }, + { .description = "240H", .value = 0x240 }, + { .description = "250H", .value = 0x250 }, + { .description = "260H", .value = 0x260 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "gus_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "512 KB", .value = 1 }, + { .description = "1 MB", .value = 2 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "adlib_ports", + .description = "Enable Adlib ports", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + const device_t gus_device = { .name = "Gravis UltraSound", .internal_name = "gus", @@ -1588,3 +1650,17 @@ const device_t gus_max_device = { .force_redraw = NULL, .config = gus_max_config }; + +const device_t gus_ace_device = { + .name = "Gravis UltraSound ACE", + .internal_name = "gusace", + .flags = DEVICE_ISA16, + .local = GUS_ACE, + .init = gus_init, + .close = gus_close, + .reset = gus_reset, + .available = NULL, + .speed_changed = gus_speed_changed, + .force_redraw = NULL, + .config = gus_ace_config +}; diff --git a/src/sound/sound.c b/src/sound/sound.c index 579056359..2fe740e5c 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -139,6 +139,7 @@ static const SOUND_CARD sound_cards[] = { { &cs4236b_device }, { &gus_device }, { &gus_max_device }, + { &gus_ace_device }, { &mirosound_pcm10_device }, { &pas16_device }, { &pas16d_device }, From cb96d4e1bc2aeb32bc26e473368b0dd859cbea25 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 10 Sep 2025 17:52:06 +0500 Subject: [PATCH 061/138] Add the Gravis UltraSound revision 3.7 Implement the ICS-2101 mixer chip that it has --- src/include/86box/sound.h | 1 + src/sound/snd_gus.c | 242 ++++++++++++++++++++++++++++++++++++-- src/sound/sound.c | 1 + 3 files changed, 232 insertions(+), 12 deletions(-) diff --git a/src/include/86box/sound.h b/src/include/86box/sound.h index 8c223cff9..66f426413 100644 --- a/src/include/86box/sound.h +++ b/src/include/86box/sound.h @@ -205,6 +205,7 @@ extern const device_t ct5880_onboard_device; /* Gravis UltraSound family */ extern const device_t gus_device; +extern const device_t gus_v37_device; extern const device_t gus_max_device; extern const device_t gus_ace_device; diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index cc585c8db..279f86d08 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -44,11 +44,33 @@ enum { }; enum { - GUS_CLASSIC = 0, - GUS_MAX = 1, - GUS_ACE = 2, + GUS_CLASSIC = 0, + GUS_CLASSIC_37 = 1, + GUS_MAX = 2, + GUS_ACE = 3 }; +enum { + GUS_ICS2101_MIC_IN = 0, + GUS_ICS2101_LINE_IN = 1, + GUS_ICS2101_CD_IN = 2, + GUS_ICS2101_GF1_OUT = 3, + GUS_ICS2101_UNUSED = 4, + GUS_ICS2101_MASTER = 5, + GUS_ICS2101_MAX = 6 +}; + +typedef struct ics2101_chan_t { + uint8_t ctrl[2]; + double level[2]; + uint8_t pan; +} ics2101_chan_t; + +typedef struct ics2101_t { + uint8_t addr; + ics2101_chan_t channels[GUS_ICS2101_MAX]; +} ics2101_t; + typedef struct gus_t { int reset; @@ -152,6 +174,8 @@ typedef struct gus_t { uint8_t max_ctrl; ad1848_t ad1848; + + ics2101_t ics2101; } gus_t; static int gus_gf1_irqs[8] = { -1, 2, 5, 3, 7, 11, 12, 15 }; @@ -165,6 +189,12 @@ int gusfreqs[] = { double vol16bit[4096]; +double ics2101_att[128]; + +double ics2101_pan[] = { 0.35481, 0.35481, 0.35481, 0.37584, 0.47315, 0.53088, 0.59566, 0.66834, + 0.70795, + 0.74989, 0.79433, 0.84140, 0.89125, 0.94406, 1.00000, 1.00000, 1.00000 }; + void gus_write(uint16_t addr, uint8_t val, void *priv); uint8_t gus_read(uint16_t addr, void *priv); @@ -264,6 +294,10 @@ gus_write(uint16_t addr, uint8_t val, void *priv) uint16_t port; uint16_t csioport; + ics2101_t *ics2101 = &gus->ics2101; + uint8_t mixer_ch; + uint8_t mixer_lr; + if ((addr == 0x388) || (addr == 0x389)) port = addr; else @@ -705,8 +739,43 @@ gus_write(uint16_t addr, uint8_t val, void *priv) gus->reg_ctrl = val; break; case 0x306: + if (gus->type == GUS_CLASSIC_37) { + mixer_ch = (ics2101->addr >> 3) & 0x7; /* current attenuator */ + mixer_lr = ics2101->addr & 1; /* left or right channel */ + switch (ics2101->addr & 0x6) { + case 0: /* Set control */ + ics2101->channels[mixer_ch].ctrl[mixer_lr] = val & 0xF; + if ((mixer_lr == 0) && (val & 0xC)) /* copy to right channel if not normal mode */ + ics2101->channels[mixer_ch].ctrl[1] = val & 0xF; + break; + case 2: /* Set attenuator */ + switch (ics2101->channels[mixer_ch].ctrl[mixer_lr] & 0xC) { + case 0: /* Normal mode */ + ics2101->channels[mixer_ch].level[mixer_lr] = ics2101_att[val & 0x7F]; + break; + case 4: /* Stereo mode */ + ics2101->channels[mixer_ch].level[0] = ics2101_att[val & 0x7F]; + ics2101->channels[mixer_ch].level[1] = ics2101_att[val & 0x7F]; + break; + case 8: /* Balance/Pan mode */ + ics2101->channels[mixer_ch].level[0] = ics2101_att[val & 0x7F] * ics2101_pan[ics2101->channels[mixer_ch].pan + 1]; + ics2101->channels[mixer_ch].level[1] = ics2101_att[val & 0x7F] * ics2101_pan[16 - ics2101->channels[mixer_ch].pan]; + break; + } + break; + case 4: /* Set panning */ + ics2101->channels[mixer_ch].pan = val & 0xF; + break; + default: + break; + } + break; + } + fallthrough; case 0x706: - if (gus->type == GUS_MAX) { + if (gus->type == GUS_CLASSIC_37) { + gus->ics2101.addr = val & 0x3F; + } else if (gus->type == GUS_MAX) { if (gus->dma >= 4) val |= 0x10; if (gus->dma2 >= 4) @@ -900,12 +969,14 @@ gus_read(uint16_t addr, void *priv) break; case 0x306: case 0x706: - if (gus->type == GUS_MAX) + if (gus->type == GUS_CLASSIC_37) + val = 0x06; /* 3.7x - mixer, no reverse channels bug */ + else if (gus->type == GUS_MAX) val = 0x0a; /* GUS MAX */ else if (gus->type == GUS_ACE) val = 0x30; /* GUS ACE */ else - val = 0xff; /*Pre 3.7 - no mixer*/ + val = 0xff; /* Pre 3.7 - no mixer */ break; case 0x307: /*DRAM access*/ @@ -1215,12 +1286,54 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) ad1848_update(&gus->ad1848); gus_update(gus); - - for (int c = 0; c < len * 2; c++) { - if ((gus->type == GUS_MAX) && (gus->max_ctrl)) - buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); - buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; - } + if (gus->type == GUS_CLASSIC_37) + for (int c = 0; c < len * 2; c += 2) { + double temp_l = 0.0; + double temp_r = 0.0; + /* GF1 out */ + uint8_t ctrl_l = gus->ics2101.channels[GUS_ICS2101_GF1_OUT].ctrl[0]; + uint8_t ctrl_r = gus->ics2101.channels[GUS_ICS2101_GF1_OUT].ctrl[1]; + if (!(ctrl_l & 0xC)) { /* Normal mode */ + if (ctrl_l & 1) + temp_l += (double) gus->buffer[0][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[0]; + if (ctrl_l & 2) + temp_r += (double) gus->buffer[0][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[0]; + if (ctrl_r & 1) + temp_l += (double) gus->buffer[1][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[1]; + if (ctrl_r & 2) + temp_r += (double) gus->buffer[1][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[1]; + } else { /* Stereo or Balance/Pan mode */ + if (ctrl_l & 2) { /* Mono/Pan */ + temp_l += ((double) gus->buffer[0][c >> 1] + (double) gus->buffer[1][c >> 1]) * 0.5 * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[(ctrl_l & 1)]; + temp_r += ((double) gus->buffer[0][c >> 1] + (double) gus->buffer[1][c >> 1]) * 0.5 * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[!(ctrl_l & 1)]; + } else { /* Stereo/Balance */ + temp_l += (double) gus->buffer[(ctrl_l & 1)][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[(ctrl_l & 1)]; + temp_r += (double) gus->buffer[!(ctrl_l & 1)][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[!(ctrl_l & 1)]; + } + } + /* Master */ + ctrl_l = gus->ics2101.channels[GUS_ICS2101_MASTER].ctrl[0]; + ctrl_r = gus->ics2101.channels[GUS_ICS2101_MASTER].ctrl[1]; + if (!(ctrl_l & 0xC)) { /* Normal mode */ + if (ctrl_l & 1) + buffer[c] += (int32_t) (temp_l * gus->ics2101.channels[GUS_ICS2101_MASTER].level[0]); + if (ctrl_l & 2) + buffer[c + 1] += (int32_t) (temp_r * gus->ics2101.channels[GUS_ICS2101_MASTER].level[0]); + if (ctrl_r & 1) + buffer[c] += (int32_t) (temp_l * gus->ics2101.channels[GUS_ICS2101_MASTER].level[1]); + if (ctrl_r & 2) + buffer[c + 1] += (int32_t) (temp_r * gus->ics2101.channels[GUS_ICS2101_MASTER].level[1]); + } else { /* Stereo or Balance mode - no mono/pan for master */ + buffer[c] += (int32_t) (((ctrl_l & 1) ? temp_l : temp_r) * gus->ics2101.channels[GUS_ICS2101_MASTER].level[(ctrl_l & 1)]); + buffer[c + 1] += (int32_t) (((ctrl_l & 1) ? temp_r : temp_l) * gus->ics2101.channels[GUS_ICS2101_MASTER].level[!(ctrl_l & 1)]); + } + } + else + for (int c = 0; c < len * 2; c++) { + if ((gus->type == GUS_MAX) && (gus->max_ctrl)) + buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); + buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; + } if ((gus->type == GUS_MAX) && (gus->max_ctrl)) gus->ad1848.pos = 0; @@ -1228,6 +1341,17 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) gus->pos = 0; } +void +gus_filter_cd_audio(int channel, double *buffer, void *priv) +{ + const gus_t *gus = (gus_t *) priv; + /* FIXME: No channel remapping possible with the current architecture */ + if (gus->ics2101.channels[GUS_ICS2101_CD_IN].ctrl[channel] && gus->ics2101.channels[GUS_ICS2101_MASTER].ctrl[channel]) + *buffer *= gus->ics2101.channels[GUS_ICS2101_CD_IN].level[channel] * gus->ics2101.channels[GUS_ICS2101_MASTER].level[channel]; + else + *buffer *= 0.0; +} + static void gus_input_msg(void *priv, uint8_t *msg, uint32_t len) { @@ -1363,6 +1487,13 @@ gus_reset(void *priv) gus->irq_state = 0; gus->midi_irq_state = 0; + for (int i = 0; i < GUS_ICS2101_MAX; i++) { + gus->ics2101.channels[i].level[0] = gus->ics2101.channels[i].level[1] = 1.0; + gus->ics2101.channels[i].ctrl[0] = 1; + gus->ics2101.channels[i].ctrl[1] = 2; + gus->ics2101.channels[i].pan = 7; + } + gus_update_int_status(gus); } @@ -1371,6 +1502,7 @@ gus_init(UNUSED(const device_t *info)) { int c; double out = 1.0; + double gain; uint8_t gus_ram = device_get_config_int("gus_ram"); gus_t *gus = calloc(1, sizeof(gus_t)); @@ -1400,6 +1532,13 @@ gus_init(UNUSED(const device_t *info)) gus->jumper = 0x06; + for (int i = 0; i < GUS_ICS2101_MAX; i++) { + gus->ics2101.channels[i].level[0] = gus->ics2101.channels[i].level[1] = 1.0; + gus->ics2101.channels[i].ctrl[0] = 1; + gus->ics2101.channels[i].ctrl[1] = 2; + gus->ics2101.channels[i].pan = 7; + } + gus->base = device_get_config_hex16("base"); io_sethandler(gus->base, 0x0010, gus_read, NULL, NULL, gus_write, NULL, NULL, gus); @@ -1415,6 +1554,19 @@ gus_init(UNUSED(const device_t *info)) gameport_remap(gus->gameport, 0x201); } + if (gus->type == GUS_CLASSIC_37) { + /* Precalculate the attenuation table for ICS2101 */ + for (int i = 0; i < 128; i++) { + gain = (127 - i) * -0.5; + if (i < 16) + for (int j = 0; j < (16 - i); j++) + gain += -0.5 - 0.13603 * (j + 1); + ics2101_att[i] = pow(10.0, gain / 20.0); + } + + sound_set_cd_audio_filter(gus_filter_cd_audio, gus); + } + if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); ad1848_setirq(&gus->ad1848, 5); @@ -1521,6 +1673,58 @@ static const device_config_t gus_config[] = { // clang-format off }; +static const device_config_t gus_v37_config[] = { + // clang-format off + { + .name = "base", + .description = "Address", + .type = CONFIG_HEX16, + .default_string = NULL, + .default_int = 0x220, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "210H", .value = 0x210 }, + { .description = "220H", .value = 0x220 }, + { .description = "230H", .value = 0x230 }, + { .description = "240H", .value = 0x240 }, + { .description = "250H", .value = 0x250 }, + { .description = "260H", .value = 0x260 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "gus_ram", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "256 KB", .value = 0 }, + { .description = "512 KB", .value = 1 }, + { .description = "1 MB", .value = 2 }, + { NULL } + }, + .bios = { { 0 } } + }, + { + .name = "receive_input", + .description = "Receive MIDI input", + .type = CONFIG_BINARY, + .default_string = NULL, + .default_int = 1, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format off +}; + static const device_config_t gus_max_config[] = { // clang-format off { @@ -1637,6 +1841,20 @@ const device_t gus_device = { .config = gus_config }; +const device_t gus_v37_device = { + .name = "Gravis UltraSound (rev 3.7)", + .internal_name = "gusv37", + .flags = DEVICE_ISA16, + .local = GUS_CLASSIC_37, + .init = gus_init, + .close = gus_close, + .reset = gus_reset, + .available = NULL, + .speed_changed = gus_speed_changed, + .force_redraw = NULL, + .config = gus_v37_config +}; + const device_t gus_max_device = { .name = "Gravis UltraSound MAX", .internal_name = "gusmax", diff --git a/src/sound/sound.c b/src/sound/sound.c index 2fe740e5c..c2e32a7da 100644 --- a/src/sound/sound.c +++ b/src/sound/sound.c @@ -138,6 +138,7 @@ static const SOUND_CARD sound_cards[] = { { &cs4235_device }, { &cs4236b_device }, { &gus_device }, + { &gus_v37_device }, { &gus_max_device }, { &gus_ace_device }, { &mirosound_pcm10_device }, From a59eb526ed5c2dbb2accda02690edcfd42e288f9 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 11 Sep 2025 16:47:56 +0500 Subject: [PATCH 062/138] AD1848: Make CD audio input designated per-card Fixes CD audio mixer not working for GUS MAX --- src/include/86box/snd_ad1848.h | 10 ++++++++++ src/sound/snd_ad1848.c | 34 ++++++++++++++++++++++++---------- src/sound/snd_azt2316a.c | 1 + src/sound/snd_cs423x.c | 5 ++++- src/sound/snd_gus.c | 1 + src/sound/snd_optimc.c | 1 + 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index a7e38a6f8..34693c675 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -32,6 +32,14 @@ enum { AD1848_TYPE_CS4235 = 6 }; +enum { + AD1848_AUX1 = 2, + AD1848_AUX2 = 4, + AD1848_OUT = 6, + AD1848_LINE_IN = 18, + AD1848_MONO = 26 +}; + typedef struct ad1848_t { uint8_t type; uint8_t index; @@ -47,6 +55,7 @@ typedef struct ad1848_t { int16_t out_l; int16_t out_r; + int8_t cd_vol_reg; double cd_vol_l; double cd_vol_r; int fm_vol_l; @@ -86,6 +95,7 @@ extern void ad1848_write(uint16_t addr, uint8_t val, void *priv); extern void ad1848_update(ad1848_t *ad1848); extern void ad1848_speed_changed(ad1848_t *ad1848); +extern void ad1848_set_cd_audio_channel(void *priv, int channel); extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r); diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index e9a4390c0..13baca4ab 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -501,16 +501,16 @@ readonly_x: if (updatefreq) ad1848_updatefreq(ad1848); - temp = (ad1848->type < AD1848_TYPE_CS4231) ? 2 : ((ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4); - if (ad1848->regs[temp] & 0x80) - ad1848->cd_vol_l = 0; - else - ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; - temp++; - if (ad1848->regs[temp] & 0x80) - ad1848->cd_vol_r = 0; - else - ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[temp] & 0x1f]; + if (ad1848->cd_vol_reg > -1) { + if (ad1848->regs[ad1848->cd_vol_reg] & 0x80) + ad1848->cd_vol_l = 0; + else + ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[ad1848->cd_vol_reg] & 0x1f]; + if (ad1848->regs[ad1848->cd_vol_reg + 1] & 0x80) + ad1848->cd_vol_r = 0; + else + ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[ad1848->cd_vol_reg + 1] & 0x1f]; + } readonly_i: ad1848_log("AD1848: write(I%d, %02X)\n", ad1848->index, val); @@ -746,6 +746,18 @@ ad1848_poll(void *priv) } } +void +ad1848_set_cd_audio_channel(void *priv, int channel) +{ + ad1848_t *ad1848 = (ad1848_t *) priv; + + const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : 15; + if (channel > max_channel) + channel = max_channel; + + ad1848->cd_vol_reg = channel; +} + void ad1848_filter_cd_audio(int channel, double *buffer, void *priv) { @@ -837,6 +849,8 @@ ad1848_init(ad1848_t *ad1848, uint8_t type) ad1848->out_l = ad1848->out_r = 0; ad1848->fm_vol_l = ad1848->fm_vol_r = 65536; + ad1848->cd_vol_l = ad1848->cd_vol_r = 65536; + ad1848->cd_vol_reg = -1; ad1848_updatevolmask(ad1848); if (type >= AD1848_TYPE_CS4235) ad1848->fmt_mask = 0x50; diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index 76bf1b24f..65d10532f 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -1211,6 +1211,7 @@ azt_init(const device_t *info) /* wss part */ ad1848_init(&azt2316a->ad1848, device_get_config_int("codec")); + ad1848_set_cd_audio_channel(&azt2316a->ad1848, (device_get_config_int("codec") == AD1848_TYPE_CS4248) ? AD1848_AUX1 : AD1848_LINE_IN); ad1848_setirq(&azt2316a->ad1848, azt2316a->cur_wss_irq); ad1848_setdma(&azt2316a->ad1848, azt2316a->cur_wss_dma); diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index 74382a53b..5905fb64e 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -273,8 +273,10 @@ cs423x_write(uint16_t addr, uint8_t val, void *priv) } switch (dev->regs[3] & 0x0f) { case 0: /* WSS Master Control */ - if ((dev->type < CRYSTAL_CS4235) && (val & 0x80)) + if ((dev->type < CRYSTAL_CS4235) && (val & 0x80)) { ad1848_init(&dev->ad1848, dev->ad1848_type); + ad1848_set_cd_audio_channel(&dev->ad1848, AD1848_AUX2); + } val = 0x00; break; @@ -865,6 +867,7 @@ cs423x_reset(void *priv) /* Reset WSS codec. */ ad1848_init(&dev->ad1848, dev->ad1848_type); + ad1848_set_cd_audio_channel(&dev->ad1848, AD1848_AUX2); /* Reset PnP resource data, state and logical devices. */ dev->pnp_enable = 1; diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 279f86d08..af47cc250 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1569,6 +1569,7 @@ gus_init(UNUSED(const device_t *info)) if (gus->type == GUS_MAX) { ad1848_init(&gus->ad1848, AD1848_TYPE_CS4231); + ad1848_set_cd_audio_channel(&gus->ad1848, AD1848_AUX2); ad1848_setirq(&gus->ad1848, 5); ad1848_setdma(&gus->ad1848, 3); io_sethandler(0x10C + gus->base, 4, diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index d0b05741a..7d1759cfe 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -380,6 +380,7 @@ optimc_init(const device_t *info) else ad1848_init(&optimc->ad1848, AD1848_TYPE_DEFAULT); + ad1848_set_cd_audio_channel(&optimc->ad1848, (info->local & 0x100) ? AD1848_LINE_IN : AD1848_AUX1); ad1848_setirq(&optimc->ad1848, optimc->cur_wss_irq); ad1848_setdma(&optimc->ad1848, optimc->cur_wss_dma); From 14cf9ee80b3a9b79f105bbb1adf1ebd7f739ecd1 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 11 Sep 2025 16:49:38 +0500 Subject: [PATCH 063/138] AD1848: Extend `ad1848_filter_aux2` to any channel --- src/include/86box/snd_ad1848.h | 2 +- src/sound/snd_ad1848.c | 14 +++++++++----- src/sound/snd_optimc.c | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 34693c675..0656e4d02 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -97,7 +97,7 @@ extern void ad1848_update(ad1848_t *ad1848); extern void ad1848_speed_changed(ad1848_t *ad1848); extern void ad1848_set_cd_audio_channel(void *priv, int channel); extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); -extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r); +extern void ad1848_filter_channel(void* priv, int channel, double* out_l, double* out_r); extern void ad1848_init(ad1848_t *ad1848, uint8_t type); diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 13baca4ab..d721691d5 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -770,20 +770,24 @@ ad1848_filter_cd_audio(int channel, double *buffer, void *priv) } void -ad1848_filter_aux2(void *priv, double *out_l, double *out_r) +ad1848_filter_channel(void *priv, int channel, double *out_l, double *out_r) { const ad1848_t *ad1848 = (ad1848_t *) priv; - if (ad1848->regs[4] & 0x80) { + const int max_channel = (ad1848->type >= AD1848_TYPE_CS4231) ? 31 : 15; + if (channel > max_channel) + channel = max_channel; + + if (ad1848->regs[channel] & 0x80) { *out_l = 0.0; } else { - *out_l = ((*out_l) * ad1848_vols_5bits_aux_gain[ad1848->regs[4] & 0x1f]) / 65536.0; + *out_l = ((*out_l) * ad1848_vols_5bits_aux_gain[ad1848->regs[channel] & 0x1f]) / 65536.0; } - if (ad1848->regs[5] & 0x80) { + if (ad1848->regs[channel + 1] & 0x80) { *out_r = 0.0; } else { - *out_r = ((*out_r) * ad1848_vols_5bits_aux_gain[ad1848->regs[5] & 0x1f]) / 65536.0; + *out_r = ((*out_r) * ad1848_vols_5bits_aux_gain[ad1848->regs[channel + 1] & 0x1f]) / 65536.0; } } diff --git a/src/sound/snd_optimc.c b/src/sound/snd_optimc.c index 7d1759cfe..274bbd568 100644 --- a/src/sound/snd_optimc.c +++ b/src/sound/snd_optimc.c @@ -85,7 +85,7 @@ optimc_filter_opl(void *priv, double *out_l, double *out_r) if (optimc->cur_wss_enabled) { *out_l /= optimc->sb->mixer_sbpro.fm_l; *out_r /= optimc->sb->mixer_sbpro.fm_r; - ad1848_filter_aux2((void *) &optimc->ad1848, out_l, out_r); + ad1848_filter_channel((void *) &optimc->ad1848, AD1848_AUX2, out_l, out_r); } } From 1340b031ee49b94f57b15ccc97ed1d96cd83ca7e Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Thu, 11 Sep 2025 16:43:15 +0500 Subject: [PATCH 064/138] GUS: Refactor the buffer/mixer code and fix the MAX mixer's GF1 input --- src/sound/snd_gus.c | 117 +++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 46 deletions(-) diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index af47cc250..8d70e61c5 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -1277,6 +1277,58 @@ gus_poll_wave(void *priv) gus_update_int_status(gus); } +void +gus_ics2101_filter(void *priv, int channel, double *out_l, double *out_r) +{ + ics2101_t *ics2101 = (ics2101_t *) priv; + + double temp_l = 0.0; + double temp_r = 0.0; + double master_l = 0.0; + double master_r = 0.0; + + uint8_t ctrl_l = ics2101->channels[channel].ctrl[0]; + uint8_t ctrl_r = ics2101->channels[channel].ctrl[1]; + if (!(ctrl_l & 0xC)) { /* Normal mode */ + if (ctrl_l & 1) + temp_l += *out_l * ics2101->channels[channel].level[0]; + if (ctrl_l & 2) + temp_r += *out_l * ics2101->channels[channel].level[0]; + if (ctrl_r & 1) + temp_l += *out_r * ics2101->channels[channel].level[1]; + if (ctrl_r & 2) + temp_r += *out_r * ics2101->channels[channel].level[1]; + } else { /* Stereo or Balance/Pan mode */ + if (ctrl_l & 2) { /* Mono/Pan */ + temp_l = (*out_l + *out_r) * 0.5 * ics2101->channels[channel].level[(ctrl_l & 1)]; + temp_r = (*out_r + *out_l) * 0.5 * ics2101->channels[channel].level[!(ctrl_l & 1)]; + } else { /* Stereo/Balance */ + temp_l = ((ctrl_l & 1) ? *out_l : *out_r) * ics2101->channels[channel].level[(ctrl_l & 1)]; + temp_r = ((ctrl_l & 1) ? *out_r : *out_l) * ics2101->channels[channel].level[!(ctrl_l & 1)]; + } + } + + /* Master */ + ctrl_l = ics2101->channels[GUS_ICS2101_MASTER].ctrl[0]; + ctrl_r = ics2101->channels[GUS_ICS2101_MASTER].ctrl[1]; + if (!(ctrl_l & 0xC)) { /* Normal mode */ + if (ctrl_l & 1) + master_l += temp_l * ics2101->channels[GUS_ICS2101_MASTER].level[0]; + if (ctrl_l & 2) + master_r += temp_l * ics2101->channels[GUS_ICS2101_MASTER].level[0]; + if (ctrl_r & 1) + master_l += temp_r * ics2101->channels[GUS_ICS2101_MASTER].level[1]; + if (ctrl_r & 2) + master_r += temp_r * ics2101->channels[GUS_ICS2101_MASTER].level[1]; + } else { /* Stereo or Balance mode - no mono/pan for master */ + master_l = ((ctrl_l & 1) ? temp_l : temp_r) * ics2101->channels[GUS_ICS2101_MASTER].level[(ctrl_l & 1)]; + master_r = ((ctrl_l & 1) ? temp_r : temp_l) * ics2101->channels[GUS_ICS2101_MASTER].level[!(ctrl_l & 1)]; + } + + *out_l = master_l; + *out_r = master_r; +} + static void gus_get_buffer(int32_t *buffer, int len, void *priv) { @@ -1286,54 +1338,27 @@ gus_get_buffer(int32_t *buffer, int len, void *priv) ad1848_update(&gus->ad1848); gus_update(gus); - if (gus->type == GUS_CLASSIC_37) - for (int c = 0; c < len * 2; c += 2) { - double temp_l = 0.0; - double temp_r = 0.0; - /* GF1 out */ - uint8_t ctrl_l = gus->ics2101.channels[GUS_ICS2101_GF1_OUT].ctrl[0]; - uint8_t ctrl_r = gus->ics2101.channels[GUS_ICS2101_GF1_OUT].ctrl[1]; - if (!(ctrl_l & 0xC)) { /* Normal mode */ - if (ctrl_l & 1) - temp_l += (double) gus->buffer[0][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[0]; - if (ctrl_l & 2) - temp_r += (double) gus->buffer[0][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[0]; - if (ctrl_r & 1) - temp_l += (double) gus->buffer[1][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[1]; - if (ctrl_r & 2) - temp_r += (double) gus->buffer[1][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[1]; - } else { /* Stereo or Balance/Pan mode */ - if (ctrl_l & 2) { /* Mono/Pan */ - temp_l += ((double) gus->buffer[0][c >> 1] + (double) gus->buffer[1][c >> 1]) * 0.5 * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[(ctrl_l & 1)]; - temp_r += ((double) gus->buffer[0][c >> 1] + (double) gus->buffer[1][c >> 1]) * 0.5 * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[!(ctrl_l & 1)]; - } else { /* Stereo/Balance */ - temp_l += (double) gus->buffer[(ctrl_l & 1)][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[(ctrl_l & 1)]; - temp_r += (double) gus->buffer[!(ctrl_l & 1)][c >> 1] * gus->ics2101.channels[GUS_ICS2101_GF1_OUT].level[!(ctrl_l & 1)]; + for (int c = 0; c < len * 2; c += 2) { + double temp_l = 0.0; + double temp_r = 0.0; + if ((gus->type == GUS_CLASSIC_37) || (gus->type == GUS_MAX)) { + temp_l = (double) gus->buffer[0][c >> 1]; + temp_r = (double) gus->buffer[1][c >> 1]; + if (gus->type == GUS_MAX) { + if (gus->max_ctrl) { + buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); + buffer[c + 1] += (int32_t) (gus->ad1848.buffer[c + 1] / 2); } - } - /* Master */ - ctrl_l = gus->ics2101.channels[GUS_ICS2101_MASTER].ctrl[0]; - ctrl_r = gus->ics2101.channels[GUS_ICS2101_MASTER].ctrl[1]; - if (!(ctrl_l & 0xC)) { /* Normal mode */ - if (ctrl_l & 1) - buffer[c] += (int32_t) (temp_l * gus->ics2101.channels[GUS_ICS2101_MASTER].level[0]); - if (ctrl_l & 2) - buffer[c + 1] += (int32_t) (temp_r * gus->ics2101.channels[GUS_ICS2101_MASTER].level[0]); - if (ctrl_r & 1) - buffer[c] += (int32_t) (temp_l * gus->ics2101.channels[GUS_ICS2101_MASTER].level[1]); - if (ctrl_r & 2) - buffer[c + 1] += (int32_t) (temp_r * gus->ics2101.channels[GUS_ICS2101_MASTER].level[1]); - } else { /* Stereo or Balance mode - no mono/pan for master */ - buffer[c] += (int32_t) (((ctrl_l & 1) ? temp_l : temp_r) * gus->ics2101.channels[GUS_ICS2101_MASTER].level[(ctrl_l & 1)]); - buffer[c + 1] += (int32_t) (((ctrl_l & 1) ? temp_r : temp_l) * gus->ics2101.channels[GUS_ICS2101_MASTER].level[!(ctrl_l & 1)]); - } - } - else - for (int c = 0; c < len * 2; c++) { - if ((gus->type == GUS_MAX) && (gus->max_ctrl)) - buffer[c] += (int32_t) (gus->ad1848.buffer[c] / 2); - buffer[c] += (int32_t) gus->buffer[c & 1][c >> 1]; + ad1848_filter_channel(&gus->ad1848, AD1848_AUX1, &temp_l, &temp_r); + } else + gus_ics2101_filter(&gus->ics2101, GUS_ICS2101_GF1_OUT, &temp_l, &temp_r); + buffer[c] += (int32_t) temp_l; + buffer[c + 1] += (int32_t) temp_r; + } else { + buffer[c] += (int32_t) gus->buffer[0][c >> 1]; + buffer[c + 1] += (int32_t) gus->buffer[1][c >> 1]; } + } if ((gus->type == GUS_MAX) && (gus->max_ctrl)) gus->ad1848.pos = 0; From bf8a64067afecf9c465bb2da965a2a7d515b3534 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Fri, 12 Sep 2025 02:03:42 +0700 Subject: [PATCH 065/138] Bring back Trangg Bow's change, now with AT clones Until it gets added to The Retro Web, this is assumed now. --- src/machine/machine_table.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index d26f5e396..f47c43c35 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3588,8 +3588,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 512, - .step = 256 + .max = 1024, /* assumed; more can be added via memory expansions */ + .step = 128 }, .nvrmask = 63, .jumpered_ecp_dma = 0, @@ -3632,8 +3632,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 512, - .step = 256 + .max = 1024, /* assumed; more can be added via memory expansions */ + .step = 128 }, .nvrmask = 63, .jumpered_ecp_dma = 0, @@ -3853,8 +3853,8 @@ const machine_t machines[] = { .flags = MACHINE_FLAGS_NONE, .ram = { .min = 256, - .max = 512, - .step = 256 + .max = 1024, /* assumed; more can be added via memory expansions */ + .step = 128 }, .nvrmask = 63, .jumpered_ecp_dma = 0, From a71e5ea0724667acb80fa256fb32b2ccb06f11a8 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 12 Sep 2025 01:23:12 +0200 Subject: [PATCH 066/138] Last minute changes for the IDE hdd (September 12th, 2025) When a secondary slave is shadowed by an ATAPI secondary master, make sure the signature (and on reset too) doesn't make it "recognized" (0xeb14) in the cylinder register (as in, 0x0000'ing it) --- src/disk/hdc_ide.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index b034fa3e3..e8c9fb05e 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -812,7 +812,7 @@ ide_set_signature(ide_t *ide) ide->tf->sector = 1; ide->tf->head = 0; ide->tf->secount = 1; - ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW]; + ide->tf->cylinder = (ide->type == IDE_ATAPI_SHADOW) ? 0x0000 : ide_signatures[ide->type & ~IDE_SHADOW]; if (ide->type == IDE_HDD) ide->drive = 0; @@ -1581,7 +1581,7 @@ ide_reset_registers(ide_t *ide) ide->tf->atastat = DRDY_STAT | DSC_STAT; ide->tf->error = 1; ide->tf->secount = 1; - ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW]; + ide->tf->cylinder = (ide->type == IDE_ATAPI_SHADOW) ? 0x0000 : ide_signatures[ide->type & ~IDE_SHADOW]; ide->tf->sector = 1; ide->tf->head = 0; From 2123f7d8f3473c0a84fcd38dc4997693d8b7403d Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Fri, 12 Sep 2025 18:55:31 +0800 Subject: [PATCH 067/138] Add Packard Bell Tacoma machine definition. --- src/include/86box/machine.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6de1586dc..b77768e0b 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1134,6 +1134,7 @@ extern int machine_at_p2bls_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_686bx_init(const machine_t *); extern int machine_at_lgibmx7g_init(const machine_t *); +extern int machine_at_tacoma_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); extern int machine_at_s1846_init(const machine_t *); From c8b705efac525e592eb029b4fe68ae98adf9991d Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:02:38 +0800 Subject: [PATCH 068/138] Add Packard Bell Tacoma machine code. --- src/machine/m_at_slot1.c | 42 ++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 12fd9861f..b34b55517 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -519,17 +519,9 @@ machine_at_686bx_init(const machine_t *model) return ret; } -int -machine_at_lgibmx7g_init(const machine_t *model) +static void +machine_at_lgibmx7g_common_init(const machine_t *model) { - int ret; - - ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); @@ -545,6 +537,36 @@ machine_at_lgibmx7g_init(const machine_t *model) device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&winbond_flash_w29c020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); +} + +int +machine_at_lgibmx7g_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_lgibmx7g_common_init(model); + + return ret; +} + +int +machine_at_tacoma_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/tacoma/A19P2190.ROM", + 0x000c0000, 262144, 0); + + if (bios_only || !ret) + return ret; + + machine_at_lgibmx7g_common_init(model); return ret; } From 0c7906b00711a4f94c67b1b02d28bdc6917ce7c7 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:07:44 +0800 Subject: [PATCH 069/138] Add Packard Bell Tacoma machine table entry. --- src/machine/machine_table.c | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f47c43c35..c7cf4cec6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -17723,6 +17723,50 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ + { + .name = "[i440BX] Packard Bell Tacoma (MSI MS-6119)", + .internal_name = "tacoma", + .type = MACHINE_TYPE_SLOT1, + .chipset = MACHINE_CHIPSET_INTEL_440BX, + .init = machine_at_tacoma_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SLOT1, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 1800, + .max_voltage = 3500, + .min_multi = 1.5, + .max_multi = 8.0 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 8192, + .max = 786432, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { From b8d83627660fbd49af4f24d3ccf4948d2ad62c4e Mon Sep 17 00:00:00 2001 From: Daniel Gurney Date: Sat, 13 Sep 2025 01:09:58 +0300 Subject: [PATCH 070/138] Finnish translation updates --- src/qt/languages/fi-FI.po | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index dc3cae0cf..47efba139 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -2959,10 +2959,10 @@ msgid "CGA composite settings" msgstr "CGA:n komposiittiasetukset" msgid "Monitor EDID" -msgstr "Monitorin EDID" +msgstr "Näytön EDID" msgid "Export..." -msgstr "Viedä..." +msgstr "Vie..." msgid "Export EDID" msgstr "Vie EDID" @@ -2971,16 +2971,16 @@ msgid "EDID file \"%ls\" is too large." msgstr "EDID-tiedosto \"%ls\" on liian suuri." msgid "OpenGL input scale" -msgstr "OpenGL:n syöttöasteikko" +msgstr "OpenGL-syötteen skaalaus" msgid "OpenGL input stretch mode" -msgstr "OpenGL:n syötteen venytystila" +msgstr "OpenGL-syötteen venytystila" msgid "Color scheme" -msgstr "Värimaailma" +msgstr "Väriteema" msgid "Light" -msgstr "Valo" +msgstr "Vaalea" msgid "Dark" msgstr "Tumma" From aae4db9e718d2871c8a8a2efe30d6bc04443537c Mon Sep 17 00:00:00 2001 From: Daniel Gurney Date: Sat, 13 Sep 2025 01:11:35 +0300 Subject: [PATCH 071/138] Fix translation deviation It wasn't really a problem before the light/dark mode selector --- src/qt/languages/fi-FI.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 47efba139..11e1c795f 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -1318,7 +1318,7 @@ msgid "Found %1" msgstr "%1 löydetty" msgid "System" -msgstr "Kone" +msgstr "Järjestelmä" msgid "Storage" msgstr "Tallennus" From b514a72bd6c68849624fcb2b8c58673c23f0891e Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Sat, 13 Sep 2025 08:24:56 +0800 Subject: [PATCH 072/138] machine.h: lgibmx76 & tacoma --> ms6119 --- src/include/86box/machine.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index b77768e0b..d28bd7dd7 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1133,8 +1133,7 @@ extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_686bx_init(const machine_t *); -extern int machine_at_lgibmx7g_init(const machine_t *); -extern int machine_at_tacoma_init(const machine_t *); +extern int machine_at_ms6119_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); extern int machine_at_s1846_init(const machine_t *); From 9d28ebe9aa3698b9f01275a935db82c5021f6154 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Sat, 13 Sep 2025 08:32:44 +0800 Subject: [PATCH 073/138] machine_table.c: lgibmx76 & tacoma --> ms6119 --- src/machine/machine_table.c | 52 +++---------------------------------- 1 file changed, 4 insertions(+), 48 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index c7cf4cec6..9e590b7f9 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -17681,11 +17681,11 @@ const machine_t machines[] = { }, /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ { - .name = "[i440BX] LG IBM Multinet i x7G (MSI MS-6119)", - .internal_name = "lgibmx7g", + .name = "[i440BX] MSI MS-6119", + .internal_name = "ms6119", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_lgibmx7g_init, + .init = machine_at_ms6119_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, @@ -17715,51 +17715,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, - /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 (updated 'H') KBC firmware. */ - { - .name = "[i440BX] Packard Bell Tacoma (MSI MS-6119)", - .internal_name = "tacoma", - .type = MACHINE_TYPE_SLOT1, - .chipset = MACHINE_CHIPSET_INTEL_440BX, - .init = machine_at_tacoma_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SLOT1, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 1800, - .max_voltage = 3500, - .min_multi = 1.5, - .max_multi = 8.0 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, - .ram = { - .min = 8192, - .max = 786432, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &ms6119_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, From 20e25aa71802d3bb9016ecc50504e2a0e0aca064 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Sat, 13 Sep 2025 08:48:00 +0800 Subject: [PATCH 074/138] Configuration is complete for MSI MS-6119. --- src/include/86box/machine.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index d28bd7dd7..7ec27dcdc 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1133,6 +1133,9 @@ extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); extern int machine_at_p3bf_init(const machine_t *); extern int machine_at_686bx_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms6119_device; +#endif extern int machine_at_ms6119_init(const machine_t *); extern int machine_at_p6sba_init(const machine_t *); extern int machine_at_s1846_init(const machine_t *); From 30d5443247f0513f7c809edcf23530ae80baab10 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Sat, 13 Sep 2025 09:12:53 +0800 Subject: [PATCH 075/138] m_at_slot1.c: MSI MS-6119 BIOS Selector Complete --- src/machine/m_at_slot1.c | 88 ++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index b34b55517..eec0dd8a8 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -519,9 +519,61 @@ machine_at_686bx_init(const machine_t *model) return ret; } -static void -machine_at_lgibmx7g_common_init(const machine_t *model) +static const device_config_t ms6119_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms6119", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "Award Modular BIOS v4.51PG - Version 3.30b1 (LG IBM Multinet i x7G)", .internal_name = "lgibmx7g", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/ms6119.331", "" } }, + { .name = "Award Modular BIOS v4.51PG - Version 2.12 (Viglen Vig69M)", .internal_name = "vig69m", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/vig69m.212", "" } }, + { .name = "Award Modular BIOS v4.51PG - Version 2.10", .internal_name = "ms6119", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/w6119ims.2a0", "" } }, + { .name = "AMIBIOS 071595 - Version 1.90 (Packard Bell Tacoma)", .internal_name = "ms6119", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/A19P2190.ROM", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms6119_device = { + .name = "MSI MS-6119", + .internal_name = "ms6119_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms6119_config +}; + +int +machine_at_ms6119_init(const machine_t *model) { + int ret = 0; + const char* fn; + + /* No ROMs available */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); @@ -539,38 +591,6 @@ machine_at_lgibmx7g_common_init(const machine_t *model) spd_register(SPD_TYPE_SDRAM, 0x7, 256); } -int -machine_at_lgibmx7g_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/lgibmx7g/ms6119.331", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_lgibmx7g_common_init(model); - - return ret; -} - -int -machine_at_tacoma_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/tacoma/A19P2190.ROM", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) - return ret; - - machine_at_lgibmx7g_common_init(model); - - return ret; -} - int machine_at_p6sba_init(const machine_t *model) { From 5a35c984e77215873ca4a1d872ba23176f8c74bf Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Sat, 13 Sep 2025 09:29:25 +0800 Subject: [PATCH 076/138] m_at_slot1.c: MSI MS-6119 BIOS Selector Complete Once Again --- src/machine/m_at_slot1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index eec0dd8a8..1abdd62a9 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -589,6 +589,8 @@ machine_at_ms6119_init(const machine_t *model) device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); device_add(&winbond_flash_w29c020_device); spd_register(SPD_TYPE_SDRAM, 0x7, 256); + + return ret; } int From 3bdedd896fee9a2c3bedf0e01881741f43e204cb Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Sat, 13 Sep 2025 09:32:02 +0800 Subject: [PATCH 077/138] m_at_slot1.c: ms6119 -> tacoma (Congratulations, MSI-MS 6119 BIOS Selector complete) --- src/machine/m_at_slot1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 1abdd62a9..a172c9396 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -536,7 +536,7 @@ static const device_config_t ms6119_config[] = { .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/vig69m.212", "" } }, { .name = "Award Modular BIOS v4.51PG - Version 2.10", .internal_name = "ms6119", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/w6119ims.2a0", "" } }, - { .name = "AMIBIOS 071595 - Version 1.90 (Packard Bell Tacoma)", .internal_name = "ms6119", .bios_type = BIOS_NORMAL, + { .name = "AMIBIOS 071595 - Version 1.90 (Packard Bell Tacoma)", .internal_name = "tacoma", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/A19P2190.ROM", "" } }, { .files_no = 0 } }, From 6f99d565e1d95434dde6c82e3c9db3cc720db2ea Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Wed, 27 Aug 2025 23:54:39 +0500 Subject: [PATCH 078/138] Manager: Pass certain command-line params to VMs --- src/86box.c | 2 ++ src/include/86box/86box.h | 1 + src/qt/qt_vmmanager_system.cpp | 14 ++++++++++++++ 3 files changed, 17 insertions(+) diff --git a/src/86box.c b/src/86box.c index 0b5a26131..d242b40b9 100644 --- a/src/86box.c +++ b/src/86box.c @@ -230,6 +230,7 @@ int other_scsi_present = 0; /* SCSI contro int is_pcjr = 0; /* The current machine is PCjr. */ int portable_mode = 0; /* We are running in portable mode (global dirs = exe path) */ +int global_cfg_overridden = 0; /* Global config file was overriden on command line */ int monitor_edid = 0; /* (C) Which EDID to use. 0=default, 1=custom. */ char monitor_edid_path[1024] = { 0 }; /* (C) Path to custom EDID */ @@ -852,6 +853,7 @@ usage: if ((c + 1) == argc || plat_dir_check(argv[c + 1])) goto usage; + global_cfg_overridden = 1; global = argv[++c]; } else if (!strcasecmp(argv[c], "--image") || !strcasecmp(argv[c], "-I")) { if ((c + 1) == argc) diff --git a/src/include/86box/86box.h b/src/include/86box/86box.h index ce39652bc..33749d440 100644 --- a/src/include/86box/86box.h +++ b/src/include/86box/86box.h @@ -202,6 +202,7 @@ extern char vmm_path[1024]; /* VM Manager path to scan */ extern int start_vmm; /* the current execution will start the manager */ extern int portable_mode; /* we are running in portable mode (global dirs = exe path) */ +extern int global_cfg_overridden; /* global config file was overriden on command line */ extern int monitor_edid; /* (C) Which EDID to use. 0=default, 1=custom. */ extern char monitor_edid_path[1024]; /* (C) Path to custom EDID */ diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index 8079f1ba0..1ddfb4cc3 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -425,6 +425,16 @@ VMManagerSystem::launchMainProcess() { QStringList args; args << "--vmpath" << config_dir; args << "--vmname" << displayName; + if (rom_path[0] != '\0') + args << "--rompath" << QString(rom_path); + if (global_cfg_overridden) + args << "--global" << QString(global_cfg_path); + if (!hook_enabled) + args << "--nohook"; + if (start_in_fullscreen) + args << "--fullscreen"; + if (!confirm_exit_cmdl) + args << "--noconfirm"; process->setProgram(program); process->setArguments(args); qDebug() << Q_FUNC_INFO << " Full Command:" << process->program() << " " << process->arguments(); @@ -481,6 +491,10 @@ VMManagerSystem::launchSettings() { QStringList open_command_args; QStringList args; args << "--vmpath" << config_dir << "--settings"; + if (rom_path[0] != '\0') + args << "--rompath" << QString(rom_path); + if (global_cfg_overridden) + args << "--global" << QString(global_cfg_path); process->setProgram(program); process->setArguments(args); qDebug() << Q_FUNC_INFO << " Full Command:" << process->program() << " " << process->arguments(); From 43bbe351fcf02af805c3bb7e259ec7a98c322b53 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 13 Sep 2025 17:12:43 +0500 Subject: [PATCH 079/138] Manager: Fix detail sections with empty entries not being hidden --- src/qt/qt_vmmanager_detailsection.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_vmmanager_detailsection.cpp b/src/qt/qt_vmmanager_detailsection.cpp index afb71a5f0..ac321be1e 100644 --- a/src/qt/qt_vmmanager_detailsection.cpp +++ b/src/qt/qt_vmmanager_detailsection.cpp @@ -161,7 +161,8 @@ VMManagerDetailSection::setupMainLayout() void VMManagerDetailSection::setSections() { - int row = 0; + int row = 0; + bool empty = true; for (const auto& section : sections) { QStringList sectionsToAdd = section.value.split(sectionSeparator); @@ -189,12 +190,13 @@ VMManagerDetailSection::setSections() const auto hSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); frameGridLayout->addItem(hSpacer, row, 2); + empty = false; row++; } } collapseButton->setContent(ui->detailFrame); - if (sections.size()) + if (!empty) setVisible(true); } void From b351811d6585f924b631ae6f43d123e47fc76ef7 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 13 Sep 2025 19:11:01 +0500 Subject: [PATCH 080/138] Manager: Fix 86B_CD 3.50 and 8x CD-ROM speed not showing in details pane --- src/qt/qt_vmmanager_system.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index 1ddfb4cc3..988d3ed5e 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -725,7 +725,7 @@ VMManagerSystem::setupVars() { } static auto floppy_match = QRegularExpression("fdd_\\d\\d_type", QRegularExpression::CaseInsensitiveOption); - static auto cdrom_match = QRegularExpression("cdrom_\\d\\d_type", QRegularExpression::CaseInsensitiveOption); + static auto cdrom_match = QRegularExpression("cdrom_\\d\\d_parameters", QRegularExpression::CaseInsensitiveOption); for(const auto& key: floppy_cdrom_config.keys()) { if(key.contains(floppy_match)) { // auto device_number = key.split("_").at(1); @@ -741,22 +741,23 @@ VMManagerSystem::setupVars() { } if(key.contains(cdrom_match)) { auto device_number = key.split("_").at(1); - auto cdrom_internal_name = QString(floppy_cdrom_config[key]); + auto cdrom_parameters = QString(floppy_cdrom_config[key]); + auto cdrom_bus = cdrom_parameters.split(",").at(1).trimmed().toUpper(); + + auto cdrom_type_key = QString("cdrom_%1_type").arg(device_number); + auto cdrom_internal_name = QString(floppy_cdrom_config[cdrom_type_key]); + if (cdrom_internal_name.isEmpty()) + cdrom_internal_name = "86cd"; auto cdrom_type = cdrom_get_from_internal_name(cdrom_internal_name.toUtf8().data()); auto cdrom_speed_key = QString("cdrom_%1_speed").arg(device_number); - auto cdrom_parameters_key = QString("cdrom_%1_parameters").arg(device_number); auto cdrom_speed = QString(floppy_cdrom_config[cdrom_speed_key]); - auto cdrom_parameters = QString(floppy_cdrom_config[cdrom_parameters_key]); - auto cdrom_bus = cdrom_parameters.split(",").at(1).trimmed().toUpper(); + if (cdrom_speed.isEmpty()) + cdrom_speed = "8"; - if(cdrom_type != -1) { - if(!cdrom_speed.isEmpty()) { - cdrom_speed = QString("%1x ").arg(cdrom_speed); - } - if(!cdrom_bus.isEmpty()) { - cdrom_bus = QString(" (%1)").arg(cdrom_bus); - } + if ((cdrom_bus != "NONE") && (cdrom_type != -1)) { + cdrom_speed = QString("%1x ").arg(cdrom_speed); + cdrom_bus = QString(" (%1)").arg(cdrom_bus); cdromDevices.append(QString("%1%2 %3 %4%5").arg(cdrom_speed, cdrom_drive_types[cdrom_type].vendor, cdrom_drive_types[cdrom_type].model, cdrom_drive_types[cdrom_type].revision, cdrom_bus)); } } From b722d03e6928257007ec5f8af5e35cc374d4aee5 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 13 Sep 2025 20:53:45 +0500 Subject: [PATCH 081/138] Manager: Remember the machine list size in addition to window size and position --- src/qt/qt_vmmanager_main.cpp | 12 ++++++++++++ src/qt/qt_vmmanager_main.hpp | 3 +++ src/qt/qt_vmmanager_mainwindow.cpp | 12 ++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index cc3904e97..7235f4500 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -740,6 +740,18 @@ VMManagerMain::machineCountString(QString states) const return tr("VMs: %1").arg(states); } +QList +VMManagerMain::getPaneSizes() const +{ + return ui->splitter->sizes(); +} + +void +VMManagerMain::setPaneSizes(const QList &sizes) +{ + ui->splitter->setSizes(sizes); +} + void VMManagerMain::modelDataChange() { diff --git a/src/qt/qt_vmmanager_main.hpp b/src/qt/qt_vmmanager_main.hpp index 070f30398..404a90fc6 100644 --- a/src/qt/qt_vmmanager_main.hpp +++ b/src/qt/qt_vmmanager_main.hpp @@ -87,6 +87,9 @@ public slots: void onConfigUpdated(const QString &uuid); int getActiveMachineCount(); + QList getPaneSizes() const; + void setPaneSizes(const QList &sizes); + private: Ui::VMManagerMain *ui; diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index f698f1ccd..f36045df3 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -151,10 +151,20 @@ VMManagerMainWindow(QWidget *parent) if (!!config->getStringValue("window_maximized").toInt()) { setWindowState(windowState() | Qt::WindowMaximized); } + + list = config->getStringValue("window_splitter").split(','); + for (auto& cur : list) { + cur = cur.trimmed(); + } + QList paneSizes; + paneSizes.append(list[0].toInt()); + paneSizes.append(list[1].toInt()); + vmm->setPaneSizes(paneSizes); } else { config->setStringValue("window_remember", ""); config->setStringValue("window_coordinates", ""); config->setStringValue("window_maximized", ""); + config->setStringValue("window_splitter", ""); } delete config; } @@ -218,10 +228,12 @@ VMManagerMainWindow::saveSettings() const if (ui->actionRemember_size_and_position->isChecked()) { config->setStringValue("window_coordinates", QString::asprintf("%i, %i, %i, %i", this->geometry().x(), this->geometry().y(), this->geometry().width(), this->geometry().height())); config->setStringValue("window_maximized", this->isMaximized() ? "1" : ""); + config->setStringValue("window_splitter", QString::asprintf("%i, %i", vmm->getPaneSizes()[0], vmm->getPaneSizes()[1])); } else { config->setStringValue("window_remember", ""); config->setStringValue("window_coordinates", ""); config->setStringValue("window_maximized", ""); + config->setStringValue("window_splitter", ""); } // Sometimes required to ensure the settings save before the app exits config->sync(); From cd6a1487ded2f4df75d0e152ef589fae88d7bd95 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 13 Sep 2025 21:58:29 +0500 Subject: [PATCH 082/138] Manager: Move the "remember size & position" option to Preferences dialog --- src/qt/languages/86box.pot | 3 ++ src/qt/languages/cs-CZ.po | 3 ++ src/qt/languages/de-DE.po | 3 ++ src/qt/languages/es-ES.po | 3 ++ src/qt/languages/fi-FI.po | 3 ++ src/qt/languages/fr-FR.po | 3 ++ src/qt/languages/hr-HR.po | 3 ++ src/qt/languages/it-IT.po | 3 ++ src/qt/languages/ja-JP.po | 3 ++ src/qt/languages/ko-KR.po | 3 ++ src/qt/languages/nb-NO.po | 3 ++ src/qt/languages/nl-NL.po | 3 ++ src/qt/languages/pl-PL.po | 3 ++ src/qt/languages/pt-BR.po | 3 ++ src/qt/languages/pt-PT.po | 3 ++ src/qt/languages/ru-RU.po | 3 ++ src/qt/languages/sk-SK.po | 3 ++ src/qt/languages/sl-SI.po | 3 ++ src/qt/languages/sv-SE.po | 3 ++ src/qt/languages/tr-TR.po | 3 ++ src/qt/languages/uk-UA.po | 3 ++ src/qt/languages/vi-VN.po | 3 ++ src/qt/languages/zh-CN.po | 3 ++ src/qt/languages/zh-TW.po | 3 ++ src/qt/qt_vmmanager_mainwindow.cpp | 50 ++++++++++++++++------------- src/qt/qt_vmmanager_mainwindow.ui | 9 ------ src/qt/qt_vmmanager_preferences.cpp | 3 ++ src/qt/qt_vmmanager_preferences.ui | 8 +++++ 28 files changed, 110 insertions(+), 32 deletions(-) diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index df6f01f3c..bae56c279 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -51,6 +51,9 @@ msgstr "" msgid "R&emember size && position" msgstr "" +msgid "Remember size && position" +msgstr "" + msgid "Re&nderer" msgstr "" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 6cef7611c..6c46c7538 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -51,6 +51,9 @@ msgstr "&Měnitelná velikost okna" msgid "R&emember size && position" msgstr "&Pamatovat velikost a pozici" +msgid "Remember size && position" +msgstr "Pamatovat velikost a pozici" + msgid "Re&nderer" msgstr "&Renderer" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 3b92f7ec3..6fb621242 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -51,6 +51,9 @@ msgstr "G&rößenverstellbares Fenster" msgid "R&emember size && position" msgstr "Größe && &Position merken" +msgid "Remember size && position" +msgstr "Größe && Position merken" + msgid "Re&nderer" msgstr "Re&nderer" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 46bd759fe..92a80869b 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -51,6 +51,9 @@ msgstr "Ven&tana redimensionable" msgid "R&emember size && position" msgstr "&Recordar tamaño y posición" +msgid "Remember size && position" +msgstr "Recordar tamaño y posición" + msgid "Re&nderer" msgstr "Re&nderizador" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index 11e1c795f..f5957db4c 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -51,6 +51,9 @@ msgstr "&Salli koon muuttaminen" msgid "R&emember size && position" msgstr "&Muista koko ja sijainti" +msgid "Remember size && position" +msgstr "Muista koko ja sijainti" + msgid "Re&nderer" msgstr "&Renderöijä" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index c31b4c8a6..b11c0c8b6 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -51,6 +51,9 @@ msgstr "Fenêtre &redimensionnable" msgid "R&emember size && position" msgstr "S&auvegarder taille && position" +msgid "Remember size && position" +msgstr "Sauvegarder taille && position" + msgid "Re&nderer" msgstr "Moteur de re&ndu vidéo" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index 4f2d8ee93..d3acd499e 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -51,6 +51,9 @@ msgstr "&Prozor s promjenjivim veličinama" msgid "R&emember size && position" msgstr "&Zapamtite veličinu i položaj" +msgid "Remember size && position" +msgstr "Zapamtite veličinu i položaj" + msgid "Re&nderer" msgstr "&Renderer" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 4c0a6722a..443831788 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -51,6 +51,9 @@ msgstr "&Finestra ridimensionabile" msgid "R&emember size && position" msgstr "R&icorda dimensioni e posizione" +msgid "Remember size && position" +msgstr "Ricorda dimensioni e posizione" + msgid "Re&nderer" msgstr "Re&nderizzatore" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 2fb7da257..21bb1a88d 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -51,6 +51,9 @@ msgstr "ウィンドウのサイズを変更可能(&R)" msgid "R&emember size && position" msgstr "ウィンドウのサイズと位置を保存(&E)" +msgid "Remember size && position" +msgstr "ウィンドウのサイズと位置を保存" + msgid "Re&nderer" msgstr "レンダラー(&N)" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index a9fa55f5b..68bd5d8c2 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -51,6 +51,9 @@ msgstr "창 크기 조절 가능하게 하기(&R)" msgid "R&emember size && position" msgstr "창 크기와 위치를 기억하기(&E)" +msgid "Remember size && position" +msgstr "창 크기와 위치를 기억하기" + msgid "Re&nderer" msgstr "렌더러(&N)" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index 53115d4b1..ec1574fa3 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -51,6 +51,9 @@ msgstr "&Justerbart vindu" msgid "R&emember size && position" msgstr "H&usk størrelse &og plassering" +msgid "Remember size && position" +msgstr "Husk størrelse og plassering" + msgid "Re&nderer" msgstr "Re&nderer" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index acc3526ec..ea92f69ec 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -51,6 +51,9 @@ msgstr "&Venster met aanpasbare grootte" msgid "R&emember size && position" msgstr "&Onthoud grootte && positie" +msgid "Remember size && position" +msgstr "Onthoud grootte && positie" + msgid "Re&nderer" msgstr "Re&nderer" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 81bedb546..6fdddd253 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -51,6 +51,9 @@ msgstr "&Okno o zmiennym rozmiarze" msgid "R&emember size && position" msgstr "P&amiętaj rozmiar i pozycję" +msgid "Remember size && position" +msgstr "Pamiętaj rozmiar i pozycję" + msgid "Re&nderer" msgstr "Re&nderer" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 211d39f16..fe162c540 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -51,6 +51,9 @@ msgstr "&Janela redimensionável" msgid "R&emember size && position" msgstr "&Lembrar tamanho e posição" +msgid "Remember size && position" +msgstr "Lembrar tamanho e posição" + msgid "Re&nderer" msgstr "&Renderizador" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index bd7894f6e..66fbfa500 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -51,6 +51,9 @@ msgstr "&Janela redimensionável" msgid "R&emember size && position" msgstr "&Lembrar tamanho e posição" +msgid "Remember size && position" +msgstr "Lembrar tamanho e posição" + msgid "Re&nderer" msgstr "&Renderizador" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 6535b6603..a9b9c3c18 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -51,6 +51,9 @@ msgstr "&Изменяемый размер окна" msgid "R&emember size && position" msgstr "&Запомнить размер и положение" +msgid "Remember size && position" +msgstr "Запомнить размер и положение" + msgid "Re&nderer" msgstr "&Рендеринг" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 20f86033c..67d2aacca 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -51,6 +51,9 @@ msgstr "&Premenná veľkosť okna" msgid "R&emember size && position" msgstr "&Pamätať si veľkosť a polohu" +msgid "Remember size && position" +msgstr "Pamätať si veľkosť a polohu" + msgid "Re&nderer" msgstr "&Renderer" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 0813e3d83..4046d4700 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -51,6 +51,9 @@ msgstr "S&premenljiva velikost okna" msgid "R&emember size && position" msgstr "&Zapomni si velikost in položaj" +msgid "Remember size && position" +msgstr "Zapomni si velikost in položaj" + msgid "Re&nderer" msgstr "&Upodabljanje" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index e3db6d3b7..4622aceda 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -51,6 +51,9 @@ msgstr "&Ändringsbar fönsterstorlek" msgid "R&emember size && position" msgstr "K&om ihåg storlek && position" +msgid "Remember size && position" +msgstr "Kom ihåg storlek && position" + msgid "Re&nderer" msgstr "Re&nderare" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 65eb47152..8bf374091 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -51,6 +51,9 @@ msgstr "&Boyutlandırılabilir pencere" msgid "R&emember size && position" msgstr "&Pencere boyut ve pozisyonunu kaydet" +msgid "Remember size && position" +msgstr "Pencere boyut ve pozisyonunu kaydet" + msgid "Re&nderer" msgstr "Derley&ici" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 79f5763c3..e5a714ad1 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -51,6 +51,9 @@ msgstr "&Змінний розмір вікна" msgid "R&emember size && position" msgstr "&Запам'ятати розмір і становище" +msgid "Remember size && position" +msgstr "Запам'ятати розмір і становище" + msgid "Re&nderer" msgstr "&Рендеринг" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index f316c54c2..a19394b79 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -51,6 +51,9 @@ msgstr "Tùy chỉnh cỡ cử&a sổ" msgid "R&emember size && position" msgstr "Ghi nhớ vị trí và kíc&h thước cửa sổ" +msgid "Remember size && position" +msgstr "Ghi nhớ vị trí và kích thước cửa sổ" + msgid "Re&nderer" msgstr "Re&nderer" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 31a34da90..921f3f64e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -51,6 +51,9 @@ msgstr "窗口大小可调(&R)" msgid "R&emember size && position" msgstr "记住窗口大小和位置(&E)" +msgid "Remember size && position" +msgstr "记住窗口大小和位置" + msgid "Re&nderer" msgstr "渲染器(&N)" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 7dcb3638f..771e67daf 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -51,6 +51,9 @@ msgstr "視窗大小可調(&R)" msgid "R&emember size && position" msgstr "記住視窗大小和位置(&E)" +msgid "Remember size && position" +msgstr "記住視窗大小和位置" + msgid "Re&nderer" msgstr "渲染器(&N)" diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index f36045df3..a4ae61577 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -135,33 +135,39 @@ VMManagerMainWindow(QWidget *parent) { auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); - this->ui->actionRemember_size_and_position->setChecked(!!config->getStringValue("window_remember").toInt()); - if (ui->actionRemember_size_and_position->isChecked()) { - QStringList list = config->getStringValue("window_coordinates").split(','); - for (auto& cur : list) { - cur = cur.trimmed(); - } - QRect geom; - geom.setX(list[0].toInt()); - geom.setY(list[1].toInt()); - geom.setWidth(list[2].toInt()); - geom.setHeight(list[3].toInt()); + if (!!config->getStringValue("window_remember").toInt()) { + QString coords = config->getStringValue("window_coordinates"); + if (!coords.isEmpty()) { + QStringList list = coords.split(','); + for (auto& cur : list) { + cur = cur.trimmed(); + } + QRect geom; + geom.setX(list[0].toInt()); + geom.setY(list[1].toInt()); + geom.setWidth(list[2].toInt()); + geom.setHeight(list[3].toInt()); + + setGeometry(geom); + } - setGeometry(geom); if (!!config->getStringValue("window_maximized").toInt()) { setWindowState(windowState() | Qt::WindowMaximized); } - list = config->getStringValue("window_splitter").split(','); - for (auto& cur : list) { - cur = cur.trimmed(); + QString splitter = config->getStringValue("window_splitter"); + if (!splitter.isEmpty()) { + QStringList list = splitter.split(','); + for (auto& cur : list) { + cur = cur.trimmed(); + } + QList paneSizes; + paneSizes.append(list[0].toInt()); + paneSizes.append(list[1].toInt()); + + vmm->setPaneSizes(paneSizes); } - QList paneSizes; - paneSizes.append(list[0].toInt()); - paneSizes.append(list[1].toInt()); - vmm->setPaneSizes(paneSizes); } else { - config->setStringValue("window_remember", ""); config->setStringValue("window_coordinates", ""); config->setStringValue("window_maximized", ""); config->setStringValue("window_splitter", ""); @@ -224,13 +230,11 @@ VMManagerMainWindow::saveSettings() const const auto currentSelection = vmm->getCurrentSelection(); const auto config = new VMManagerConfig(VMManagerConfig::ConfigType::General); config->setStringValue("last_selection", currentSelection); - config->setStringValue("window_remember", QString::number(ui->actionRemember_size_and_position->isChecked())); - if (ui->actionRemember_size_and_position->isChecked()) { + if (!!config->getStringValue("window_remember").toInt()) { config->setStringValue("window_coordinates", QString::asprintf("%i, %i, %i, %i", this->geometry().x(), this->geometry().y(), this->geometry().width(), this->geometry().height())); config->setStringValue("window_maximized", this->isMaximized() ? "1" : ""); config->setStringValue("window_splitter", QString::asprintf("%i, %i", vmm->getPaneSizes()[0], vmm->getPaneSizes()[1])); } else { - config->setStringValue("window_remember", ""); config->setStringValue("window_coordinates", ""); config->setStringValue("window_maximized", ""); config->setStringValue("window_splitter", ""); diff --git a/src/qt/qt_vmmanager_mainwindow.ui b/src/qt/qt_vmmanager_mainwindow.ui index 15739628d..7cd817a0b 100644 --- a/src/qt/qt_vmmanager_mainwindow.ui +++ b/src/qt/qt_vmmanager_mainwindow.ui @@ -28,7 +28,6 @@ &Tools - @@ -187,14 +186,6 @@ New machine... - - - true - - - R&emember size && position - - &Preferences... diff --git a/src/qt/qt_vmmanager_preferences.cpp b/src/qt/qt_vmmanager_preferences.cpp index b709b0b13..d181119f4 100644 --- a/src/qt/qt_vmmanager_preferences.cpp +++ b/src/qt/qt_vmmanager_preferences.cpp @@ -70,6 +70,8 @@ VMManagerPreferences(QWidget *parent) : ui(new Ui::VMManagerPreferences) #endif const auto useRegexSearch = config->getStringValue("regex_search").toInt(); ui->regexSearchCheckBox->setChecked(useRegexSearch); + const auto rememberSizePosition = config->getStringValue("window_remember").toInt(); + ui->rememberSizePositionCheckBox->setChecked(rememberSizePosition); ui->radioButtonSystem->setChecked(color_scheme == 0); ui->radioButtonLight->setChecked(color_scheme == 1); @@ -112,6 +114,7 @@ VMManagerPreferences::accept() #if EMU_BUILD_NUM != 0 config->setStringValue("update_check", ui->updateCheckBox->isChecked() ? "1" : "0"); #endif + config->setStringValue("window_remember", ui->rememberSizePositionCheckBox->isChecked() ? "1" : "0"); config->setStringValue("regex_search", ui->regexSearchCheckBox->isChecked() ? "1" : "0"); QDialog::accept(); } diff --git a/src/qt/qt_vmmanager_preferences.ui b/src/qt/qt_vmmanager_preferences.ui index ab96109e6..7f7b94fa4 100644 --- a/src/qt/qt_vmmanager_preferences.ui +++ b/src/qt/qt_vmmanager_preferences.ui @@ -92,6 +92,13 @@ + + + + Remember size && position + + + @@ -165,6 +172,7 @@ dirSelectButton comboBoxLanguage pushButtonLanguage + rememberSizePositionCheckBox updateCheckBox regexSearchCheckBox From 416983110213b82a3d141bf91bb668a80bdf9366 Mon Sep 17 00:00:00 2001 From: Alexander Babikov Date: Sat, 13 Sep 2025 21:59:16 +0500 Subject: [PATCH 083/138] Manager: Add machine actions to context menu --- src/qt/languages/86box.pot | 8 +++++- src/qt/languages/cs-CZ.po | 8 +++++- src/qt/languages/de-DE.po | 10 +++++-- src/qt/languages/es-ES.po | 10 +++++-- src/qt/languages/fi-FI.po | 10 +++++-- src/qt/languages/fr-FR.po | 10 +++++-- src/qt/languages/hr-HR.po | 10 +++++-- src/qt/languages/it-IT.po | 10 +++++-- src/qt/languages/ja-JP.po | 10 +++++-- src/qt/languages/ko-KR.po | 10 +++++-- src/qt/languages/nb-NO.po | 10 +++++-- src/qt/languages/nl-NL.po | 10 +++++-- src/qt/languages/pl-PL.po | 10 +++++-- src/qt/languages/pt-BR.po | 10 +++++-- src/qt/languages/pt-PT.po | 10 +++++-- src/qt/languages/ru-RU.po | 10 +++++-- src/qt/languages/sk-SK.po | 8 +++++- src/qt/languages/sl-SI.po | 10 +++++-- src/qt/languages/sv-SE.po | 10 +++++-- src/qt/languages/tr-TR.po | 10 +++++-- src/qt/languages/uk-UA.po | 10 +++++-- src/qt/languages/vi-VN.po | 8 +++++- src/qt/languages/zh-CN.po | 10 +++++-- src/qt/languages/zh-TW.po | 10 +++++-- src/qt/qt_mainwindow.ui | 2 +- src/qt/qt_vmmanager_main.cpp | 47 +++++++++++++++++++++++++++++++ src/qt/qt_vmmanager_mainwindow.ui | 11 +++++++- 27 files changed, 246 insertions(+), 46 deletions(-) diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index bae56c279..41b84f5b0 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -15,7 +15,7 @@ msgstr "" msgid "&Right CTRL is left ALT" msgstr "" -msgid "&Hard Reset..." +msgid "&Hard reset" msgstr "" msgid "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "" msgid "Start" msgstr "" +msgid "&Force shutdown" +msgstr "" + +msgid "&Start" +msgstr "" + msgid "Not running" msgstr "" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 6c46c7538..9e74cdef9 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -15,7 +15,7 @@ msgstr "&Klávesnice vyžaduje záběr myši" msgid "&Right CTRL is left ALT" msgstr "&Pravý Ctrl je levý Alt" -msgid "&Hard Reset..." +msgid "&Hard reset" msgstr "&Resetovat" msgid "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Vynutit vypnutí" msgid "Start" msgstr "Spustit" +msgid "&Force shutdown" +msgstr "&Vynutit vypnutí" + +msgid "&Start" +msgstr "&Spustit" + msgid "Not running" msgstr "Neběží" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 6fb621242..4984af9fd 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -15,8 +15,8 @@ msgstr "&Tastatur benötigt das Einfangen des Mauszeigers" msgid "&Right CTRL is left ALT" msgstr "&Die rechte Strg-Taste ist die linke Alt-Taste" -msgid "&Hard Reset..." -msgstr "&Kaltstart..." +msgid "&Hard reset" +msgstr "&Kaltstart" msgid "&Ctrl+Alt+Del" msgstr "&Strg+Alt+Entf" @@ -1077,6 +1077,12 @@ msgstr "Abschaltung erzwingen" msgid "Start" msgstr "Einschalten" +msgid "&Force shutdown" +msgstr "&Abschaltung erzwingen" + +msgid "&Start" +msgstr "&Einschalten" + msgid "Not running" msgstr "Läuft nicht" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 92a80869b..5516b7b6d 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -15,8 +15,8 @@ msgstr "&Teclado requiere captura" msgid "&Right CTRL is left ALT" msgstr "CTRL &derecho es ALT izquierdo" -msgid "&Hard Reset..." -msgstr "&Hard Reset..." +msgid "&Hard reset" +msgstr "&Hard reset" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Apagqar forzadamente" msgid "Start" msgstr "Iniciar" +msgid "&Force shutdown" +msgstr "&Apagqar forzadamente" + +msgid "&Start" +msgstr "&Iniciar" + msgid "Not running" msgstr "No en ejecución" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index f5957db4c..996762a2d 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -15,8 +15,8 @@ msgstr "&Vaadi näppäimistön kaappaus" msgid "&Right CTRL is left ALT" msgstr "&Oikea CTRL on vasen ALT" -msgid "&Hard Reset..." -msgstr "&Uudelleenkäynnistys (kylmä)..." +msgid "&Hard reset" +msgstr "&Uudelleenkäynnistys (kylmä)" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Pakota sammutus" msgid "Start" msgstr "Käynnistä" +msgid "&Force shutdown" +msgstr "&Pakota sammutus" + +msgid "&Start" +msgstr "&Käynnistä" + msgid "Not running" msgstr "Ei käynnissä" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index b11c0c8b6..17fdcb1be 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -15,8 +15,8 @@ msgstr "C&apturer le clavier" msgid "&Right CTRL is left ALT" msgstr "CTRL &Droite devient ALT Gauche" -msgid "&Hard Reset..." -msgstr "&Hard Reset..." +msgid "&Hard reset" +msgstr "&Hard reset" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Suppr" @@ -1077,6 +1077,12 @@ msgstr "Arrêt forcé" msgid "Start" msgstr "Démarrer" +msgid "&Force shutdown" +msgstr "&Arrêt forcé" + +msgid "&Start" +msgstr "&Démarrer" + msgid "Not running" msgstr "Inactive" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index d3acd499e..3a2c239b2 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -15,8 +15,8 @@ msgstr "&Tipkovnica zahtijeva hvatanje miša" msgid "&Right CTRL is left ALT" msgstr "&Desni CTRL je lijevi ALT" -msgid "&Hard Reset..." -msgstr "&Ponovno pokretanje..." +msgid "&Hard reset" +msgstr "&Ponovno pokretanje" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Prisilno isključi" msgid "Start" msgstr "Pokreni" +msgid "&Force shutdown" +msgstr "Prisilno &isključi" + +msgid "&Start" +msgstr "&Pokreni" + msgid "Not running" msgstr "Se ne pokreće" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index 443831788..65c4d83dd 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -15,8 +15,8 @@ msgstr "&Tastiera richiede la cattura" msgid "&Right CTRL is left ALT" msgstr "CTRL &destro è ALT sinistro" -msgid "&Hard Reset..." -msgstr "&Riavvia..." +msgid "&Hard reset" +msgstr "&Riavvia" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Canc" @@ -1077,6 +1077,12 @@ msgstr "Forza arresto" msgid "Start" msgstr "Avvia" +msgid "&Force shutdown" +msgstr "&Forza arresto" + +msgid "&Start" +msgstr "&Avvia" + msgid "Not running" msgstr "Inattivo" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 21bb1a88d..5c1973295 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -15,8 +15,8 @@ msgstr "キーボードはキャプチャが必要(&K)" msgid "&Right CTRL is left ALT" msgstr "右CTRLを左ALTへ変換(&R)" -msgid "&Hard Reset..." -msgstr "ハード リセット(&H)..." +msgid "&Hard reset" +msgstr "ハード リセット(&H)" msgid "&Ctrl+Alt+Del" msgstr "Ctrl+Alt+Del(&C)" @@ -1077,6 +1077,12 @@ msgstr "強制終了" msgid "Start" msgstr "スタート" +msgid "&Force shutdown" +msgstr "強制終了(&F)" + +msgid "&Start" +msgstr "スタート(&S)" + msgid "Not running" msgstr "停止した" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 68bd5d8c2..caa87823a 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -15,8 +15,8 @@ msgstr "키보드는 캡쳐가 필요함(&K)" msgid "&Right CTRL is left ALT" msgstr "우측CTRL로 좌측ALT 입력(&R)" -msgid "&Hard Reset..." -msgstr "재시작(&H)..." +msgid "&Hard reset" +msgstr "재시작(&H)" msgid "&Ctrl+Alt+Del" msgstr "Ctrl+Alt+Del(&C)" @@ -1077,6 +1077,12 @@ msgstr "강제 종료" msgid "Start" msgstr "시작" +msgid "&Force shutdown" +msgstr "강제 종료(&F)" + +msgid "&Start" +msgstr "시작(&S)" + msgid "Not running" msgstr "실행 중이 아닙니다" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index ec1574fa3..f883b3fac 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -15,8 +15,8 @@ msgstr "&Tastatur krever opptak" msgid "&Right CTRL is left ALT" msgstr "&Høyre CTRL er venstre ALT" -msgid "&Hard Reset..." -msgstr "&Hard tilbakestilling..." +msgid "&Hard reset" +msgstr "&Hard tilbakestilling" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Tvangsavslutt" msgid "Start" msgstr "Start" +msgid "&Force shutdown" +msgstr "&Tvangsavslutt" + +msgid "&Start" +msgstr "&Start" + msgid "Not running" msgstr "Ikke kjørende" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index ea92f69ec..763a9192d 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -15,8 +15,8 @@ msgstr "&Keyboard vereist vastleggen" msgid "&Right CTRL is left ALT" msgstr "&Rechtse CTRL is linkse ALT" -msgid "&Hard Reset..." -msgstr "&Harde Reset..." +msgid "&Hard reset" +msgstr "&Harde reset" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Forceer afsluiten" msgid "Start" msgstr "Start" +msgid "&Force shutdown" +msgstr "&Forceer afsluiten" + +msgid "&Start" +msgstr "&Start" + msgid "Not running" msgstr "Niet actied" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 6fdddd253..a46abb6ce 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -15,8 +15,8 @@ msgstr "&Klawiatura wymaga przechwytu myszy" msgid "&Right CTRL is left ALT" msgstr "Prawy C&TRL to lewy ALT" -msgid "&Hard Reset..." -msgstr "Twardy &reset..." +msgid "&Hard reset" +msgstr "Twardy &reset" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Wymuś zamknięcie" msgid "Start" msgstr "Uruchom" +msgid "&Force shutdown" +msgstr "&Wymuś zamknięcie" + +msgid "&Start" +msgstr "&Uruchom" + msgid "Not running" msgstr "Wyłączona" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index fe162c540..1a49ace23 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -15,8 +15,8 @@ msgstr "O &teclado requer captura" msgid "&Right CTRL is left ALT" msgstr "CTR&L direito é o ALT esquerdo" -msgid "&Hard Reset..." -msgstr "&Reinicialização completa..." +msgid "&Hard reset" +msgstr "&Reinicialização completa" msgid "&Ctrl+Alt+Del" msgstr "Ctrl+Alt+&Del" @@ -1077,6 +1077,12 @@ msgstr "Forçar desligamento" msgid "Start" msgstr "Iniciar" +msgid "&Force shutdown" +msgstr "&Forçar desligamento" + +msgid "&Start" +msgstr "&Iniciar" + msgid "Not running" msgstr "Parado" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index 66fbfa500..cdbf065f6 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -15,8 +15,8 @@ msgstr "&Teclado requere captura" msgid "&Right CTRL is left ALT" msgstr "CTRL &direito é ALT esquerdo" -msgid "&Hard Reset..." -msgstr "&Reinicialização completa..." +msgid "&Hard reset" +msgstr "&Reinicialização completa" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Desligamento forçado" msgid "Start" msgstr "Iniciar" +msgid "&Force shutdown" +msgstr "&Desligamento forçado" + +msgid "&Start" +msgstr "&Iniciar" + msgid "Not running" msgstr "Não em execução" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index a9b9c3c18..20a25371f 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -15,8 +15,8 @@ msgstr "&Клавиатура требует захвата" msgid "&Right CTRL is left ALT" msgstr "&Правый CTRL - это левый ALT" -msgid "&Hard Reset..." -msgstr "&Холодная перезагрузка..." +msgid "&Hard reset" +msgstr "&Холодная перезагрузка" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Принудительное завершение работы" msgid "Start" msgstr "Пуск" +msgid "&Force shutdown" +msgstr "Принудительное &завершение работы" + +msgid "&Start" +msgstr "&Пуск" + msgid "Not running" msgstr "Не работает" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index 67d2aacca..399bee502 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -15,7 +15,7 @@ msgstr "&Klávesnica vyžaduje záber" msgid "&Right CTRL is left ALT" msgstr "&Pravý Ctrl je ľavý Alt" -msgid "&Hard Reset..." +msgid "&Hard reset" msgstr "&Resetovať" msgid "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Vynútiť vypnutie" msgid "Start" msgstr "Spustiť" +msgid "&Force shutdown" +msgstr "&Vynútiť vypnutie" + +msgid "&Start" +msgstr "&Spustiť" + msgid "Not running" msgstr "Nebeží" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 4046d4700..31cb1e303 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -15,8 +15,8 @@ msgstr "&Tipkovnica potrebuje zajem" msgid "&Right CTRL is left ALT" msgstr "&Desni CTRL je levi ALT" -msgid "&Hard Reset..." -msgstr "&Ponovni zagon..." +msgid "&Hard reset" +msgstr "&Ponovni zagon" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Prisilno prekini" msgid "Start" msgstr "Zaženi" +msgid "&Force shutdown" +msgstr "&Prisilno prekini" + +msgid "&Start" +msgstr "&Zaženi" + msgid "Not running" msgstr "Se ne izvaja" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index 4622aceda..890bc18eb 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -15,8 +15,8 @@ msgstr "&Tangentbord behöver uppfångas" msgid "&Right CTRL is left ALT" msgstr "&Höger CTRL är vänster ALT" -msgid "&Hard Reset..." -msgstr "&Hård omstart..." +msgid "&Hard reset" +msgstr "&Hård omstart" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Tvinga avstängning" msgid "Start" msgstr "Starta" +msgid "&Force shutdown" +msgstr "&Tvinga avstängning" + +msgid "&Start" +msgstr "&Starta" + msgid "Not running" msgstr "Körs ej" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index 8bf374091..3df51363c 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -15,8 +15,8 @@ msgstr "&Klavye sadece fare yakalandığında çalışsın" msgid "&Right CTRL is left ALT" msgstr "&Sağ CTRL tuşunu sol ALT tuşu olarak ayarla" -msgid "&Hard Reset..." -msgstr "Yeniden başlamaya &zorla..." +msgid "&Hard reset" +msgstr "Yeniden başlamaya &zorla" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Kapatmaya zorla" msgid "Start" msgstr "Başlat" +msgid "&Force shutdown" +msgstr "&Kapatmaya zorla" + +msgid "&Start" +msgstr "&Başlat" + msgid "Not running" msgstr "Çalışmıyor" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index e5a714ad1..5e2dc7a1e 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -15,8 +15,8 @@ msgstr "&Клавіатура потребує захвату" msgid "&Right CTRL is left ALT" msgstr "&Правий CTRL - це лівий ALT" -msgid "&Hard Reset..." -msgstr "&Холодне перезавантаження..." +msgid "&Hard reset" +msgstr "&Холодне перезавантаження" msgid "&Ctrl+Alt+Del" msgstr "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Примусове завершення роботи" msgid "Start" msgstr "Пуск" +msgid "&Force shutdown" +msgstr "Примусове &завершення роботи" + +msgid "&Start" +msgstr "&Пуск" + msgid "Not running" msgstr "Не працює" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index a19394b79..632c43c12 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -15,7 +15,7 @@ msgstr "Bàn phím &hoạt động cần 'bắt' chuột" msgid "&Right CTRL is left ALT" msgstr "Gắn ALT trái vào CTRL ph&ải" -msgid "&Hard Reset..." +msgid "&Hard reset" msgstr "Buộc khởi độn&g lại" msgid "&Ctrl+Alt+Del" @@ -1077,6 +1077,12 @@ msgstr "Buộc tắt nguồn máy" msgid "Start" msgstr "Khởi động" +msgid "&Force shutdown" +msgstr "&Buộc tắt nguồn máy" + +msgid "&Start" +msgstr "&Khởi động" + msgid "Not running" msgstr "Đang không chạy" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index 921f3f64e..7e92f9aee 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -15,8 +15,8 @@ msgstr "键盘需要捕捉(&K)" msgid "&Right CTRL is left ALT" msgstr "将右 CTRL 键映射为左 ALT 键(&R)" -msgid "&Hard Reset..." -msgstr "硬重置(&H)..." +msgid "&Hard reset" +msgstr "硬重置(&H)" msgid "&Ctrl+Alt+Del" msgstr "Ctrl+Alt+Del(&C)" @@ -1077,6 +1077,12 @@ msgstr "强制关机" msgid "Start" msgstr "启动" +msgid "&Force shutdown" +msgstr "强制关机(&F)" + +msgid "&Start" +msgstr "启动(&S)" + msgid "Not running" msgstr "未在运行" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 771e67daf..fff385f34 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -15,8 +15,8 @@ msgstr "鍵盤需要捕捉(&K)" msgid "&Right CTRL is left ALT" msgstr "將右 CTRL 鍵映射為左 ALT 鍵(&R)" -msgid "&Hard Reset..." -msgstr "硬重設(&H)..." +msgid "&Hard reset" +msgstr "硬重設(&H)" msgid "&Ctrl+Alt+Del" msgstr "Ctrl+Alt+Del(&C)" @@ -1077,6 +1077,12 @@ msgstr "強制關機" msgid "Start" msgstr "開始" +msgid "&Force shutdown" +msgstr "強制關機(&F)" + +msgid "&Start" +msgstr "開始(&S)" + msgid "Not running" msgstr "未執行" diff --git a/src/qt/qt_mainwindow.ui b/src/qt/qt_mainwindow.ui index 78cb2df98..ca7aca2ca 100644 --- a/src/qt/qt_mainwindow.ui +++ b/src/qt/qt_mainwindow.ui @@ -340,7 +340,7 @@ :/menuicons/qt/icons/hard_reset.ico:/menuicons/qt/icons/hard_reset.ico - &Hard Reset... + &Hard reset false diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 7235f4500..99c1c9a67 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -109,6 +109,53 @@ VMManagerMain::VMManagerMain(QWidget *parent) : if (indexAt.isValid()) { QMenu contextMenu(tr("Context Menu"), ui->listView); + QAction startAction(tr("&Start")); + contextMenu.addAction(&startAction); + connect(&startAction, &QAction::triggered, [this] { + selected_sysconfig->startButtonPressed(); + }); + startAction.setEnabled(selected_sysconfig->process->state() == QProcess::NotRunning); + startAction.setVisible(selected_sysconfig->process->state() == QProcess::NotRunning); + + QAction pauseAction(tr("&Pause")); + contextMenu.addAction(&pauseAction); + connect(&pauseAction, &QAction::triggered, [this] { + selected_sysconfig->pauseButtonPressed(); + }); + pauseAction.setEnabled(selected_sysconfig->process->state() == QProcess::Running); + pauseAction.setVisible(selected_sysconfig->process->state() == QProcess::Running); + if (selected_sysconfig->getProcessStatus() != VMManagerSystem::ProcessStatus::Running) + pauseAction.setText(tr("Re&sume")); + + QAction resetAction(tr("&Hard reset")); + contextMenu.addAction(&resetAction); + connect(&resetAction, &QAction::triggered, [this] { + selected_sysconfig->restartButtonPressed(); + }); + resetAction.setEnabled(selected_sysconfig->process->state() == QProcess::Running); + + QAction forceShutdownAction(tr("&Force shutdown")); + contextMenu.addAction(&forceShutdownAction); + connect(&forceShutdownAction, &QAction::triggered, [this] { + selected_sysconfig->shutdownForceButtonPressed(); + }); + forceShutdownAction.setEnabled(selected_sysconfig->process->state() == QProcess::Running); + + QAction cadAction(tr("&Ctrl+Alt+Del")); + contextMenu.addAction(&cadAction); + connect(&cadAction, &QAction::triggered, [this] { + selected_sysconfig->cadButtonPressed(); + }); + cadAction.setEnabled(selected_sysconfig->process->state() == QProcess::Running); + + contextMenu.addSeparator(); + + QAction settingsAction(tr("&Settings...")); + contextMenu.addAction(&settingsAction); + connect(&settingsAction, &QAction::triggered, [this] { + selected_sysconfig->launchSettings(); + }); + QAction nameChangeAction(tr("Change &display name...")); contextMenu.addAction(&nameChangeAction); // Use a lambda to call a function so indexAt can be passed diff --git a/src/qt/qt_vmmanager_mainwindow.ui b/src/qt/qt_vmmanager_mainwindow.ui index 7cd817a0b..c45e83741 100644 --- a/src/qt/qt_vmmanager_mainwindow.ui +++ b/src/qt/qt_vmmanager_mainwindow.ui @@ -98,6 +98,9 @@ &Start + + Start + false @@ -108,7 +111,10 @@ :/menuicons/qt/icons/hard_reset.ico:/menuicons/qt/icons/hard_reset.ico - &Hard Reset... + &Hard reset + + + Hard reset false @@ -167,6 +173,9 @@ &Settings... + + Settings... + QAction::NoRole From e18fb752fdd2a3103bf8eaac1721d1dccce337e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= <13226155+dhrdlicka@users.noreply.github.com> Date: Sat, 13 Sep 2025 21:07:17 +0200 Subject: [PATCH 084/138] Update Czech translation [skip ci] Updated translations for OpenGL input scale, stretch mode, and light/dark terminology. --- src/qt/languages/cs-CZ.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 9e74cdef9..b1864c5c2 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -2980,16 +2980,16 @@ msgid "EDID file \"%ls\" is too large." msgstr "Soubor EDID \"%ls\" je příliš velký." msgid "OpenGL input scale" -msgstr "Vstupní měřítko OpenGL" +msgstr "Měřítko vstupu OpenGL" msgid "OpenGL input stretch mode" -msgstr "režim roztažení vstupu OpenGL" +msgstr "Režim roztažení vstupu OpenGL" msgid "Color scheme" msgstr "Barevné schéma" msgid "Light" -msgstr "Světlo" +msgstr "Světlé" msgid "Dark" -msgstr "Tmavá" +msgstr "Tmavé" From 25ee59d98c4f54a9a2b13f8d6a7feec93f2695a9 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 13 Sep 2025 16:32:43 -0300 Subject: [PATCH 085/138] Fix internal name for Multitech PC-900 --- src/include/86box/machine.h | 2 +- src/machine/m_at_286.c | 6 ++++-- src/machine/machine_table.c | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6de1586dc..77aff35ce 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -498,7 +498,7 @@ extern int machine_at_cmdpc_init(const machine_t *); extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_grid1520_init(const machine_t *); -extern int machine_at_mpfpc900_init(const machine_t *); +extern int machine_at_pc900_init(const machine_t *); extern int machine_at_mr286_init(const machine_t *); extern int machine_at_pc8_init(const machine_t *); extern int machine_at_m290_init(const machine_t *); diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index a1b71a817..a2a69716b 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -305,7 +305,8 @@ machine_at_portableiii_init(const machine_t *model) } int -machine_at_grid1520_init(const machine_t *model) { +machine_at_grid1520_init(const machine_t *model) +{ int ret = 0; ret = bios_load_linear("roms/machines/grid1520/grid1520_891025.rom", @@ -329,7 +330,8 @@ machine_at_grid1520_init(const machine_t *model) { } int -machine_at_mpfpc900_init(const machine_t *model) { +machine_at_pc900_init(const machine_t *model) +{ int ret = 0; ret = bios_load_linear("roms/machines/pc900/mpf_pc900_v207a.bin", diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index f47c43c35..97b71cdb6 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3345,10 +3345,10 @@ const machine_t machines[] = { /* Has IBM AT KBC firmware. */ { .name = "[ISA] Multitech PC-900", - .internal_name = "mpfpc900", + .internal_name = "pc900", .type = MACHINE_TYPE_286, .chipset = MACHINE_CHIPSET_DISCRETE, - .init = machine_at_mpfpc900_init, + .init = machine_at_pc900_init, .p1_handler = machine_generic_p1_handler, .gpio_handler = NULL, .available_flag = MACHINE_AVAILABLE, From d92112fa2dd6afa0e47a539808b0af9dafe60ebd Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 13 Sep 2025 17:00:15 -0300 Subject: [PATCH 086/138] Add "screenshot mode" compile flag to round % and Hz displays --- src/86box.c | 6 ++++++ src/CMakeLists.txt | 4 ++++ src/qt/qt_mainwindow.cpp | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index d242b40b9..44b6793e4 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1866,6 +1866,12 @@ pc_run(void) if (title_update) { mouse_msg_idx = ((mouse_type == MOUSE_TYPE_NONE) || (mouse_input_mode >= 1)) ? 2 : !!mouse_capture; +#ifdef SCREENSHOT_MODE + if (force_10ms) + fps = ((fps + 2) / 5) * 5; + else + fps = ((fps + 20) / 50) * 50; +#endif swprintf(temp, sizeof_w(temp), mouse_msg[mouse_msg_idx], fps / (force_10ms ? 1 : 10), force_10ms ? 0 : (fps % 10)); #ifdef __APPLE__ /* Needed due to modifying the UI on the non-main thread is a big no-no. */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec3b2c628..b13071241 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -84,6 +84,10 @@ if(DEBUGREGS486) add_compile_definitions(USE_DEBUG_REGS_486) endif() +if(SCREENSHOT_MODE) + add_compile_definitions(SCREENSHOT_MODE) +endif() + if(VNC) find_package(LibVNCServer) if(LibVNCServer_FOUND) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 1c2e000ab..4f616e61b 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -200,7 +200,11 @@ MainWindow::MainWindow(QWidget *parent) frameRateTimer->setInterval(1000); frameRateTimer->setSingleShot(false); connect(frameRateTimer, &QTimer::timeout, [hertz_label] { - hertz_label->setText(tr("%1 Hz").arg(QString::number(monitors[0].mon_actualrenderedframes.load()) + (monitors[0].mon_interlace ? "i" : ""))); + auto hz = monitors[0].mon_actualrenderedframes.load(); +#ifdef SCREENSHOT_MODE + hz = ((hz + 2) / 5) * 5; +#endif + hertz_label->setText(tr("%1 Hz").arg(QString::number(hz) + (monitors[0].mon_interlace ? "i" : ""))); }); statusBar()->addPermanentWidget(hertz_label); frameRateTimer->start(1000); From ccc5c3aec17832c6ec1ebe028a1091eee4c5a3ac Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 13 Sep 2025 17:05:30 -0300 Subject: [PATCH 087/138] Fix strncpy warnings --- src/86box.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/86box.c b/src/86box.c index 44b6793e4..18681d743 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1153,11 +1153,13 @@ usage: start_vmm = 1; } else { strncpy(vmm_path, vmm_path_cfg, sizeof(vmm_path) - 1); + vmm_path[sizeof(vmm_path) - 1] = '\0'; } if (start_vmm) { pclog("# VM Manager enabled. Path: %s\n", vmm_path); strncpy(usr_path, vmm_path, sizeof(usr_path) - 1); + usr_path[sizeof(usr_path) - 1] = '\0'; } else #endif { From fcf236ff7ec25927947ac7527a812c262207efc7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Sep 2025 23:09:24 +0200 Subject: [PATCH 088/138] Add the selection of the last BIOS versio of ABIT BX6. --- src/include/86box/machine.h | 3 +++ src/machine/m_at_slot1.c | 50 +++++++++++++++++++++++++++++++++---- src/machine/machine_table.c | 2 +- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 77aff35ce..9f5a7c119 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1128,6 +1128,9 @@ extern int machine_at_p6i440e2_init(const machine_t *); /* i440BX */ extern int machine_at_bf6_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t bx6_device; +#endif extern int machine_at_bx6_init(const machine_t *); extern int machine_at_ax6bc_init(const machine_t *); extern int machine_at_p2bls_init(const machine_t *); diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 12fd9861f..b3a4a2857 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -348,17 +348,57 @@ machine_at_bf6_init(const machine_t *model) return ret; } +static const device_config_t bx6_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "bx6", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "1998/07/28 - BIOS EG", .internal_name = "bx6", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/bx6/BX6_EG.BIN", "" } }, + { .name = "2000/03/10 - BIOS QS", .internal_name = "bx6_qs", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/bx6/BX6_QS.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t bx6_device = { + .name = "ABIT BX6", + .internal_name = "bx6_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = bx6_config +}; + int machine_at_bx6_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/bx6/BX6_EG.BIN", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 97b71cdb6..2d5d81f10 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -17491,7 +17491,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &bx6_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, From d08b21b34a472fb03a805d854efcd925d2aa9c37 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 Sep 2025 23:20:54 +0200 Subject: [PATCH 089/138] Some machine ordering fixes (and a 286 machine had the wrong chipset displayed). --- src/include/86box/machine.h | 16 +++---- src/machine/m_at_286.c | 44 +++++++++---------- src/machine/m_at_386sx.c | 44 +++++++++---------- src/machine/machine_table.c | 86 ++++++++++++++++++------------------- 4 files changed, 95 insertions(+), 95 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 9f5a7c119..c3abd7f7a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -516,19 +516,19 @@ extern int machine_at_dells200_init(const machine_t *); extern int machine_at_super286c_init(const machine_t *); extern int machine_at_at122_init(const machine_t *); extern int machine_at_tuliptc7_init(const machine_t *); +/* Wells American A*Star with custom award BIOS. */ +extern int machine_at_wellamerastar_init(const machine_t *); /* GC103 */ extern int machine_at_quadt286_init(const machine_t *); extern void machine_at_headland_common_init(const machine_t *model, int type); extern int machine_at_tg286m_init(const machine_t *); -/* Wells American A*Star with custom award BIOS. */ -extern int machine_at_wellamerastar_init(const machine_t *); /* NEAT */ +extern int machine_at_px286_init(const machine_t *); extern int machine_at_ataripc4_init(const machine_t *); extern int machine_at_neat_ami_init(const machine_t *); extern int machine_at_3302_init(const machine_t *); -extern int machine_at_px286_init(const machine_t *); /* SCAMP */ extern int machine_at_pc7286_init(const machine_t *); @@ -558,8 +558,8 @@ extern const device_t pbl300sx_device; extern int machine_at_pbl300sx_init(const machine_t *); /* ALi M1217 */ -extern int machine_at_arb1374_init(const machine_t *); extern int machine_at_sbc350a_init(const machine_t *); +extern int machine_at_arb1374_init(const machine_t *); extern int machine_at_flytech386_init(const machine_t *); #ifdef EMU_DEVICE_H extern const device_t c325ax_device; @@ -609,6 +609,10 @@ extern int machine_at_wd76c10_init(const machine_t *); extern int machine_at_pja511m_init(const machine_t *); extern int machine_at_prox1332_init(const machine_t *); +/* m_at_486slc.c */ +/* OPTi 283 */ +extern int machine_at_rycleopardlx_init(const machine_t *); + /* m_at_386dx.c */ /* ISA */ #ifdef EMU_DEVICE_H @@ -640,10 +644,6 @@ extern int machine_at_opti495_init(const machine_t *); extern int machine_at_asus3863364k_init(const machine_t *); extern int machine_at_asus386_init(const machine_t *); -/* m_at_486slc.c */ -/* OPTi 283 */ -extern int machine_at_rycleopardlx_init(const machine_t *); - /* m_at_386dx_486.c */ /* ALi M1429G */ extern int machine_at_exp4349_init(const machine_t *); diff --git a/src/machine/m_at_286.c b/src/machine/m_at_286.c index a2a69716b..b8e1f746a 100644 --- a/src/machine/m_at_286.c +++ b/src/machine/m_at_286.c @@ -736,6 +736,28 @@ machine_at_tg286m_init(const machine_t *model) return ret; } +int +machine_at_px286_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/px286/KENITEC.BIN", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + + if (fdc_current[0] == FDC_INTERNAL) + device_add(&fdc_at_device); + + device_add(&neat_device); + + return ret; +} + // TODO // Onboard Paradise PVGA1A-JK VGA Graphics // Data Technology Corporation DTC7187 RLL Controller (Optional) @@ -816,28 +838,6 @@ machine_at_3302_init(const machine_t *model) return ret; } -int -machine_at_px286_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/px286/KENITEC.BIN", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); - - if (fdc_current[0] == FDC_INTERNAL) - device_add(&fdc_at_device); - - device_add(&neat_device); - - return ret; -} - /* SCAMP */ int machine_at_pc7286_init(const machine_t *model) diff --git a/src/machine/m_at_386sx.c b/src/machine/m_at_386sx.c index f48b8977a..7e57c5902 100644 --- a/src/machine/m_at_386sx.c +++ b/src/machine/m_at_386sx.c @@ -162,28 +162,6 @@ machine_at_pbl300sx_init(const machine_t *model) } /* ALi M1217 */ -int -machine_at_arb1374_init(const machine_t *model) -{ - int ret; - - ret = bios_load_linear("roms/machines/arb1374/1374s.rom", - 0x000f0000, 65536, 0); - - if (bios_only || !ret) - return ret; - - machine_at_common_init(model); - - device_add(&ali1217_device); - device_add(&ide_isa_device); - device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0 | W83XX7_IDE_PRI)); - - device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); - - return ret; -} - int machine_at_sbc350a_init(const machine_t *model) { @@ -206,6 +184,28 @@ machine_at_sbc350a_init(const machine_t *model) return ret; } +int +machine_at_arb1374_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linear("roms/machines/arb1374/1374s.rom", + 0x000f0000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_common_init(model); + + device_add(&ali1217_device); + device_add(&ide_isa_device); + device_add_params(&w83877_device, (void *) (W83877F | W83877_3F0 | W83XX7_IDE_PRI)); + + device_add_params(machine_get_kbc_device(machine), (void *) model->kbc_params); + + return ret; +} + int machine_at_flytech386_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2d5d81f10..5ef248ed3 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -3916,6 +3916,49 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* has an Award-branded KBC controller */ + { + .name = "[C&T PC/AT] Hyundai Super-286C", + .internal_name = "super286c", + .type = MACHINE_TYPE_286, + .chipset = MACHINE_CHIPSET_CT_AT, + .init = machine_at_super286c_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_286, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_FLAGS_NONE, + .ram = { + .min = 512, + .max = 1024, + .step = 128 + }, + .nvrmask = 127, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_AWARD | 0x00424600, + .kbc_p1 = 0x000004f0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* No proper pictures of the KBC exist, though it seems to have the IBM AT KBC firmware. */ { @@ -4270,49 +4313,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* has an Award-branded KBC controller */ - { - .name = "[NEAT] Hyundai Super-286C", - .internal_name = "super286c", - .type = MACHINE_TYPE_286, - .chipset = MACHINE_CHIPSET_NEAT, - .init = machine_at_super286c_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_286, - .block = CPU_BLOCK_NONE, - .min_bus = 0, - .max_bus = 0, - .min_voltage = 0, - .max_voltage = 0, - .min_multi = 0, - .max_multi = 0 - }, - .bus_flags = MACHINE_AT, - .flags = MACHINE_FLAGS_NONE, - .ram = { - .min = 512, - .max = 1024, - .step = 128 - }, - .nvrmask = 127, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_AWARD | 0x00424600, - .kbc_p1 = 0x000004f0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* Has NCR KBC firmware. */ { .name = "[NEAT] NCR 3302", From 00677015b78c442cac1e5b3258fefe2266200561 Mon Sep 17 00:00:00 2001 From: Nelson Kerber Hennemann Filho <87081197+nelsonhef@users.noreply.github.com> Date: Sat, 13 Sep 2025 19:04:12 -0300 Subject: [PATCH 090/138] Fix untranslated string --- src/qt/qt_vmmanager_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 99c1c9a67..6ae455f8a 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -390,7 +390,7 @@ illegal_chars: } else { QMenu contextMenu(tr("Context Menu"), ui->listView); - QAction newMachineAction(tr("New machine...")); + QAction newMachineAction(tr("&New machine...")); contextMenu.addAction(&newMachineAction); connect(&newMachineAction, &QAction::triggered, this, &VMManagerMain::newMachineWizard); From 57a964a0151c05ac12d8eb6e38822e8898305c60 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 13 Sep 2025 19:20:40 -0300 Subject: [PATCH 091/138] Jenkins: Slight formatting fix --- .ci/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index d0a4857d9..e62bdd0be 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -600,8 +600,8 @@ then cmake_flags_extra="$cmake_flags_extra -D MOLTENVK=ON -D \"MOLTENVK_INCLUDE_DIR=$macports\"" fi - # Enable Libserialport - cmake_flags_extra="$cmake_flags_extra -D \"LIBSERIALPORT_ROOT=$macports\"" + # Enable libserialport. + cmake_flags_extra="$cmake_flags_extra -D \"LIBSERIALPORT_ROOT=$macports\"" # Install dependencies only if we're in a new build and/or MacPorts prefix. if check_buildtag "$(basename "$macports")" From 38806537fcb7d3a4b436053a02cbfebe949b544e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Sep 2025 02:00:31 +0200 Subject: [PATCH 092/138] Bump the version to 6.0. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- src/unix/assets/86Box.spec | 4 ++-- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f91d48ecc..90fcc1c0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 5.1 + VERSION 6.0 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index 61a0490ee..7772e71de 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (5.1) UNRELEASED; urgency=medium +86box (6.0) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Wed, 27 Aug 2025 19:39:16 +0200 + -- Jasmine Iwanek Sun, 14 Sep 2025 01:57:44 +0200 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index 0e57beb1c..16906ec41 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 5.1 +Version: 6.0 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Sat Aug 31 Jasmine Iwanek 5.1-1 +* Sat Aug 31 Jasmine Iwanek 6.0-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 455e6841d..629ae8a08 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -11,7 +11,7 @@ net.86box.86Box.desktop - + diff --git a/vcpkg.json b/vcpkg.json index a623508e7..6a4f6376c 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "5.1", + "version-string": "6.0", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From 57ae731e22563d67a2c284624ad5b13edfe361ce Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 14 Sep 2025 01:32:41 +0100 Subject: [PATCH 093/138] Goodbye, 32-bit --- .ci/Jenkinsfile | 6 - .ci/build.sh | 11 - .github/ISSUE_TEMPLATE/bug_report.yml | 3 - CMakeLists.txt | 2 +- cmake/flags-gcc-armv7.cmake | 20 - cmake/flags-gcc-i686.cmake | 20 - cmake/llvm-win32-i686.cmake | 30 - debian/control | 3 +- debian/rules | 16 +- src/CMakeLists.txt | 8 - src/arch_detect.c | 2 - src/codegen/CMakeLists.txt | 12 +- src/codegen/codegen.h | 2 - src/codegen/codegen_accumulate_x86.c | 66 - src/codegen/codegen_ops.c | 9 +- src/codegen/codegen_ops_x86.h | 3935 ----------------- src/codegen/codegen_x86.c | 2183 --------- src/codegen/codegen_x86.h | 45 - src/codegen_new/CMakeLists.txt | 16 +- src/codegen_new/codegen_allocator.c | 2 +- src/codegen_new/codegen_allocator.h | 12 +- src/codegen_new/codegen_backend.h | 6 +- src/codegen_new/codegen_backend_arm.c | 373 -- src/codegen_new/codegen_backend_arm.h | 24 - src/codegen_new/codegen_backend_arm_defs.h | 88 - src/codegen_new/codegen_backend_arm_ops.c | 1398 ------ src/codegen_new/codegen_backend_arm_ops.h | 252 -- src/codegen_new/codegen_backend_arm_uops.c | 3720 ---------------- src/codegen_new/codegen_backend_x86.c | 345 -- src/codegen_new/codegen_backend_x86.h | 14 - src/codegen_new/codegen_backend_x86_defs.h | 50 - src/codegen_new/codegen_backend_x86_ops.c | 1312 ------ src/codegen_new/codegen_backend_x86_ops.h | 195 - src/codegen_new/codegen_backend_x86_ops_fpu.c | 75 - src/codegen_new/codegen_backend_x86_ops_fpu.h | 5 - .../codegen_backend_x86_ops_helpers.h | 94 - src/codegen_new/codegen_backend_x86_ops_sse.c | 630 --- src/codegen_new/codegen_backend_x86_ops_sse.h | 111 - src/codegen_new/codegen_backend_x86_uops.c | 3533 --------------- src/cpu/cpu.h | 4 +- src/device/mouse_wacom_tablet.c | 2 +- src/floppy/lzf/lzfP.h | 2 +- src/include/86box/vid_voodoo_render.h | 2 +- src/unix/assets/86Box.spec | 2 +- src/unix/unix.c | 6 +- src/utils/random.c | 2 +- src/video/vid_voodoo_render.c | 4 +- 47 files changed, 30 insertions(+), 18622 deletions(-) delete mode 100644 cmake/flags-gcc-armv7.cmake delete mode 100644 cmake/flags-gcc-i686.cmake delete mode 100644 cmake/llvm-win32-i686.cmake delete mode 100644 src/codegen/codegen_accumulate_x86.c delete mode 100644 src/codegen/codegen_ops_x86.h delete mode 100644 src/codegen/codegen_x86.c delete mode 100644 src/codegen/codegen_x86.h delete mode 100644 src/codegen_new/codegen_backend_arm.c delete mode 100644 src/codegen_new/codegen_backend_arm.h delete mode 100644 src/codegen_new/codegen_backend_arm_defs.h delete mode 100644 src/codegen_new/codegen_backend_arm_ops.c delete mode 100644 src/codegen_new/codegen_backend_arm_ops.h delete mode 100644 src/codegen_new/codegen_backend_arm_uops.c delete mode 100644 src/codegen_new/codegen_backend_x86.c delete mode 100644 src/codegen_new/codegen_backend_x86.h delete mode 100644 src/codegen_new/codegen_backend_x86_defs.h delete mode 100644 src/codegen_new/codegen_backend_x86_ops.c delete mode 100644 src/codegen_new/codegen_backend_x86_ops.h delete mode 100644 src/codegen_new/codegen_backend_x86_ops_fpu.c delete mode 100644 src/codegen_new/codegen_backend_x86_ops_fpu.h delete mode 100644 src/codegen_new/codegen_backend_x86_ops_helpers.h delete mode 100644 src/codegen_new/codegen_backend_x86_ops_sse.c delete mode 100644 src/codegen_new/codegen_backend_x86_ops_sse.h delete mode 100644 src/codegen_new/codegen_backend_x86_uops.c 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; From 3e3303272e75633c32aec629d1d0b1eca19d2418 Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 14 Sep 2025 01:34:11 +0100 Subject: [PATCH 094/138] Fix compile --- src/utils/random.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/random.c b/src/utils/random.c index 880e3add3..392cad52f 100644 --- a/src/utils/random.c +++ b/src/utils/random.c @@ -19,7 +19,7 @@ #include #include <86box/random.h> -#if ! defined(__x86_64__)) +#if !defined(__x86_64__) # include #endif From fef13a41dd1d45bf4b63728a7906146192b399c1 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:16:05 -0500 Subject: [PATCH 095/138] Remove now-unnecessary is_opl3sa AD1848 mixer hack --- src/include/86box/snd_ad1848.h | 2 -- src/sound/snd_ad1848.c | 8 -------- src/sound/snd_ymf701.c | 1 - 3 files changed, 11 deletions(-) diff --git a/src/include/86box/snd_ad1848.h b/src/include/86box/snd_ad1848.h index 3105d75f9..6e8282485 100644 --- a/src/include/86box/snd_ad1848.h +++ b/src/include/86box/snd_ad1848.h @@ -70,7 +70,6 @@ typedef struct ad1848_t { uint64_t timer_latch; pc_timer_t cs4231a_irq_timer; - uint8_t is_opl3sa; int16_t buffer[SOUNDBUFLEN * 2]; int pos; @@ -91,7 +90,6 @@ extern void ad1848_update(ad1848_t *ad1848); extern void ad1848_speed_changed(ad1848_t *ad1848); extern void ad1848_filter_cd_audio(int channel, double *buffer, void *priv); extern void ad1848_filter_aux2(void* priv, double* out_l, double* out_r); -extern void ad1848_is_opl3sa(ad1848_t *ad1848); extern void ad1848_init(ad1848_t *ad1848, uint8_t type); diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index bad9f4d22..cd988a9ef 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -76,12 +76,6 @@ ad1848_setdma(ad1848_t *ad1848, int newdma) ad1848->dma = newdma; } -void -ad1848_is_opl3sa(ad1848_t *ad1848) -{ - ad1848->is_opl3sa = 1; -} - void ad1848_updatevolmask(ad1848_t *ad1848) { @@ -524,8 +518,6 @@ readonly_x: ad1848_updatefreq(ad1848); temp = (ad1848->type < AD1848_TYPE_CS4231) ? 2 : ((ad1848->type == AD1848_TYPE_CS4231) ? 18 : 4); - if (ad1848->is_opl3sa) - temp = 2; /* OPL3-SA CODEC is CS4231-based but uses Aux1 for CD audio */ if (ad1848->regs[temp] & 0x80) ad1848->cd_vol_l = 0; else diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index 1e45c786a..b18c48953 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -447,7 +447,6 @@ ymf701_init(const device_t *info) sound_add_handler(ymf701_get_buffer, ymf701); music_add_handler(sb_get_music_buffer_sbpro, ymf701->sb); - ad1848_is_opl3sa(&ymf701->ad1848); //sound_set_cd_audio_filter(sbpro_filter_cd_audio, ymf701->sb); /* CD audio filter for the default context */ sound_set_cd_audio_filter(ad1848_filter_cd_audio, &ymf701->ad1848); From 9ee210f55d2e2244cf74b66a06f2f1997aed7553 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 13 Sep 2025 22:34:25 -0500 Subject: [PATCH 096/138] Use new method of attaching OPL3 and CD audio to the AD1848 mixer --- src/sound/snd_ymf701.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index b18c48953..37f04157d 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -104,7 +104,7 @@ ymf701_filter_opl(void *priv, double *out_l, double *out_r) ymf701_t *ymf701 = (ymf701_t *) priv; if (ymf701->cur_wss_enabled) { - ad1848_filter_aux2((void *) &ymf701->ad1848, out_l, out_r); + ad1848_filter_channel((void *) &ymf701->ad1848, AD1848_AUX2, out_l, out_r); } } @@ -447,6 +447,7 @@ ymf701_init(const device_t *info) sound_add_handler(ymf701_get_buffer, ymf701); music_add_handler(sb_get_music_buffer_sbpro, ymf701->sb); + ad1848_set_cd_audio_channel(&ymf701->ad1848, AD1848_AUX1); //sound_set_cd_audio_filter(sbpro_filter_cd_audio, ymf701->sb); /* CD audio filter for the default context */ sound_set_cd_audio_filter(ad1848_filter_cd_audio, &ymf701->ad1848); From d4c9ee5613feabc88091eb7165d1bd22c6c8b51d Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sat, 13 Sep 2025 23:07:31 -0500 Subject: [PATCH 097/138] Code cleanup and comment updates --- src/sound/snd_ymf701.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index 37f04157d..4506688c5 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -65,7 +65,6 @@ static int ymf701_wss_irq[8] = { 0, 7, 9, 10, 11, 0, 0, 0 }; typedef struct ymf701_t { uint8_t type; - uint8_t fm_type; uint8_t wss_config; uint8_t reg_enabled; @@ -93,8 +92,6 @@ typedef struct ymf701_t { uint8_t regs[6]; uint8_t passwd_phase; - uint8_t oldreadback; - void * log; /* New logging system */ } ymf701_t; @@ -115,8 +112,6 @@ ymf701_wss_read(uint16_t addr, void *priv) uint8_t ret = 0x00; uint8_t port = addr - ymf701->cur_wss_addr; - ymf701_log(ymf701->log, "WSS Read port = %04X\n", port); - switch (port) { case 0: ret = ymf701->wss_config; @@ -404,11 +399,12 @@ ymf701_init(const device_t *info) ymf701->cur_wss_dma = 0; ymf701->cur_wss_irq = 11; - ymf701->regs[0] = 0xFF; + /* Power-on default values are unknown, using BIOS-initialized values from an Intel Ruby board */ + ymf701->regs[0] = 0xFF; /* Index 0 is unused, return 0xFF */ ymf701->regs[1] = 0x24; ymf701->regs[2] = 0x46; ymf701->regs[3] = 0x87; - ymf701->regs[4] = 0x00; + ymf701->regs[4] = 0x00; /* LSI version register, always returns 0 */ ymf701->log = log_open("YMF701"); @@ -448,7 +444,6 @@ ymf701_init(const device_t *info) sound_add_handler(ymf701_get_buffer, ymf701); music_add_handler(sb_get_music_buffer_sbpro, ymf701->sb); ad1848_set_cd_audio_channel(&ymf701->ad1848, AD1848_AUX1); - //sound_set_cd_audio_filter(sbpro_filter_cd_audio, ymf701->sb); /* CD audio filter for the default context */ sound_set_cd_audio_filter(ad1848_filter_cd_audio, &ymf701->ad1848); ymf701->mpu = (mpu_t *) calloc(1, sizeof(mpu_t)); From 02b09601484a50cb2d76a64690dcbfabd0cafd1a Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 14 Sep 2025 11:01:34 +0100 Subject: [PATCH 098/138] A few minor further i386 removals --- src/cpu/x87_ops.h | 10 +++------- src/floppy/lzf/lzf_d.c | 2 +- src/include/86box/bswap.h | 2 +- src/utils/random.c | 2 +- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 1e4504949..e581652d4 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -22,16 +22,12 @@ */ #include #include -#if defined(_MSC_VER) && !defined(__clang__) -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 + +#if defined _M_X64 || defined __amd64__ # define X87_INLINE_ASM -# endif -#else -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ -# define X87_INLINE_ASM -# endif #endif + #ifdef X87_INLINE_ASM #include #endif diff --git a/src/floppy/lzf/lzf_d.c b/src/floppy/lzf/lzf_d.c index f838ba674..cda3e8c8f 100644 --- a/src/floppy/lzf/lzf_d.c +++ b/src/floppy/lzf/lzf_d.c @@ -44,7 +44,7 @@ #endif #if USE_REP_MOVSB /* small win on amd, big loss on intel */ -#if (__i386 || __amd64) && __GNUC__ >= 3 +#if (__amd64) && __GNUC__ >= 3 # define lzf_movsb(dst, src, len) \ asm ("rep movsb" \ : "=D" (dst), "=S" (src), "=c" (len) \ diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index 61a6a46a2..0c32a7887 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -163,7 +163,7 @@ CPU_CONVERT(le, 64, uint64_t) /* unaligned versions (optimized for frequent unaligned accesses)*/ -#if defined(__i386__) || defined(__powerpc__) +#if defined(__powerpc__) # define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) # define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) # define le16_to_cpupu(p) le16_to_cpup(p) diff --git a/src/utils/random.c b/src/utils/random.c index 392cad52f..58abb15eb 100644 --- a/src/utils/random.c +++ b/src/utils/random.c @@ -50,7 +50,7 @@ rotr32c(uint32_t x, uint32_t n) static __inline unsigned long long rdtsc(void) { -#if defined(__i386__) || defined(__x86_64__) +#if defined(__x86_64__) unsigned int hi; unsigned int lo; # ifdef _MSC_VER From a44ad7e77667ec1592628095aa73b7879ab2b1bd Mon Sep 17 00:00:00 2001 From: starfrost013 Date: Sun, 14 Sep 2025 15:50:01 +0100 Subject: [PATCH 099/138] Remove 32-bit core dynarec --- src/86box.c | 3 - src/arch_detect.c | 4 +- src/chipset/compaq_386.c | 5 - src/cpu/386_common.h | 44 ++------- src/cpu/cpu.h | 4 - src/include/86box/machine.h | 6 +- src/include/86box/mem.h | 17 +--- src/machine/machine_table.c | 4 - src/mem/mem.c | 177 +++--------------------------------- src/mem/row.c | 22 +---- src/mem/smram.c | 15 --- src/printer/prt_ps.c | 9 +- src/qt/qt_platform.cpp | 9 +- 13 files changed, 28 insertions(+), 291 deletions(-) diff --git a/src/86box.c b/src/86box.c index 18681d743..b90591267 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1805,9 +1805,6 @@ pc_close(UNUSED(thread_t *ptr)) gdbstub_close(); -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - mem_free(); -#endif } #ifdef __APPLE__ diff --git a/src/arch_detect.c b/src/arch_detect.c index 442a44bae..4ef267c94 100644 --- a/src/arch_detect.c +++ b/src/arch_detect.c @@ -15,9 +15,7 @@ * Copyright 2020-2021 David Hrdlička. */ -#if defined(__arm__) || defined(__TARGET_ARCH_ARM) -# error ARCH arm -#elif defined(__aarch64__) || defined(_M_ARM64) +#if defined(__aarch64__) || defined(_M_ARM64) # error ARCH arm64 #elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) # error ARCH x86_64 diff --git a/src/chipset/compaq_386.c b/src/chipset/compaq_386.c index bc81c5472..9db69fd73 100644 --- a/src/chipset/compaq_386.c +++ b/src/chipset/compaq_386.c @@ -714,11 +714,6 @@ compaq_386_init(UNUSED(const device_t *info)) mem_mapping_disable(&ram_low_mapping); mem_mapping_disable(&ram_mid_mapping); mem_mapping_disable(&ram_high_mapping); -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - /* Should never be the case, but you never know what a user may set. */ - if (mem_size > 1048576) - mem_mapping_disable(&ram_2gb_mapping); -#endif /* Initialize in reverse order for memory mapping precedence reasons. */ diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index 83ef4e72b..8e1f7533f 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -357,22 +357,17 @@ fastreadb(uint32_t a) mem_debug_check_addr(a, read_type); read_type = 4; # endif + if ((a >> 12) == pccache) -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint8_t *) &pccache2[a]); -# endif + t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + return *((uint8_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint8_t *) &pccache2[a]); -# endif } static __inline uint16_t @@ -392,22 +387,16 @@ fastreadw(uint32_t a) return val; } if ((a >> 12) == pccache) -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint16_t *) &pccache2[a]); -# endif + t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint16_t *) &pccache2[a]); -# endif } static __inline uint32_t @@ -431,11 +420,8 @@ fastreadl(uint32_t a) pccache2 = t; pccache = a >> 12; } -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + return *((uint32_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint32_t *) &pccache2[a]); -# endif } val = fastreadw(a); val |= (fastreadw(a + 2) << 16); @@ -447,18 +433,10 @@ static __inline void * get_ram_ptr(uint32_t a) { if ((a >> 12) == pccache) -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return (void *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL)); -#else - return &pccache2[a]; -#endif else { uint8_t *t = getpccache(a); -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return (void *) (((uintptr_t) &t[a] & 0x00000000ffffffffULL) | ((uintptr_t) &t[0] & 0xffffffff00000000ULL)); -#else - return &t[a]; -#endif } } @@ -528,22 +506,16 @@ fastreadw_fetch(uint32_t a) return val; } if ((a >> 12) == pccache) -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint16_t *) &pccache2[a]); -# endif t = getpccache(a); if (cpu_state.abrt) return 0; pccache = a >> 12; pccache2 = t; -# if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) + return *((uint16_t *) (((uintptr_t) &pccache2[a] & 0x00000000ffffffffULL) | ((uintptr_t) &pccache2[0] & 0xffffffff00000000ULL))); -# else - return *((uint16_t *) &pccache2[a]); -# endif + } static __inline uint32_t diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 5f78ef2ef..9f6ce23cc 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -388,10 +388,6 @@ typedef struct { uint32_t old_fp_control; uint32_t new_fp_control; # endif -# if defined _M_IX86 - uint16_t old_fp_control2; - uint16_t new_fp_control2; -# endif # if defined __amd64__ || defined _M_X64 uint32_t trunc_fp_control; # endif diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index f5868f534..4431590a6 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -174,11 +174,7 @@ #define CPU_BLOCK_NONE 0 /* Make sure it's always an invalid value to avoid misdetections. */ -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) -# define MACHINE_AVAILABLE 0xffffffffffffffffULL -#else -# define MACHINE_AVAILABLE 0xffffffff -#endif +#define MACHINE_AVAILABLE 0xffffffffffffffffULL enum { MACHINE_TYPE_NONE = 0, diff --git a/src/include/86box/mem.h b/src/include/86box/mem.h index 8710fca51..f75f1175e 100644 --- a/src/include/86box/mem.h +++ b/src/include/86box/mem.h @@ -265,24 +265,17 @@ extern uint32_t biosmask; extern uint32_t biosaddr; extern int readlookup[256]; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -extern uintptr_t *readlookup2; -#endif extern uintptr_t old_rl2; extern uint8_t uncached; extern int readlnext; extern int writelookup[256]; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -extern uintptr_t *writelookup2; -#endif + extern int writelnext; extern uint32_t ram_mapped_addr[64]; extern uint8_t page_ff[4096]; extern mem_mapping_t ram_low_mapping; -#if 1 extern mem_mapping_t ram_mid_mapping; -#endif extern mem_mapping_t ram_remapped_mapping; extern mem_mapping_t ram_high_mapping; extern mem_mapping_t ram_2gb_mapping; @@ -292,16 +285,11 @@ extern mem_mapping_t bios_high_mapping; extern uint32_t mem_logical_addr; extern page_t *pages; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -extern page_t **page_lookup; -#endif -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) /* The lookup tables. */ extern page_t *page_lookup[1048576]; extern uintptr_t readlookup2[1048576]; extern uintptr_t writelookup2[1048576]; -#endif extern uint32_t get_phys_virt; extern uint32_t get_phys_phys; @@ -470,9 +458,6 @@ extern void mem_a20_init(void); extern void mem_a20_recalc(void); extern void mem_init(void); -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -extern void mem_free(void); -#endif extern void mem_close(void); extern void mem_zero(void); extern void mem_reset(void); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index a4113addc..1ade65c81 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -19589,11 +19589,7 @@ machine_get_min_ram(int m) int machine_get_max_ram(int m) { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - return MIN(((int) machines[m].ram.max), 2097152); -#else return MIN(((int) machines[m].ram.max), 3145728); -#endif } int diff --git a/src/mem/mem.c b/src/mem/mem.c index a544f333c..b4225372d 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -67,9 +67,6 @@ mem_mapping_t bios_mapping; mem_mapping_t bios_high_mapping; page_t *pages; /* RAM page table */ -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -page_t **page_lookup; /* pagetable lookup */ -#endif uint32_t pages_sz; /* #pages in table */ uint8_t *ram; /* the virtual RAM */ @@ -87,23 +84,16 @@ uint8_t *pccache2; int readlnext; int readlookup[256]; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -uintptr_t *readlookup2; -#endif uintptr_t old_rl2; uint8_t uncached = 0; int writelnext; int writelookup[256]; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -uintptr_t *writelookup2; -#endif -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) /* The lookup tables. */ page_t *page_lookup[1048576] = { 0 }; uintptr_t readlookup2[1048576] = { 0 }; uintptr_t writelookup2[1048576] = { 0 }; -#endif + uint32_t mem_logical_addr; @@ -147,12 +137,7 @@ static uint8_t ff_pccache[4] = { 0xff, 0xff, 0xff, 0xff }; static mem_state_t _mem_state[MEM_MAPPINGS_NO]; static uint32_t remap_start_addr; static uint32_t remap_start_addr2; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) static size_t ram_size = 0; -static size_t ram2_size = 0; -#else -static size_t ram_size = 0; -#endif #ifdef ENABLE_MEM_LOG int mem_do_log = ENABLE_MEM_LOG; @@ -274,24 +259,10 @@ void mem_flush_write_page(uint32_t addr, uint32_t virt) { const page_t *page_target = &pages[addr >> 12]; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - uint32_t a; -#endif for (uint16_t c = 0; c < 256; c++) { if (writelookup[c] != (int) 0xffffffff) { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) uintptr_t target = (uintptr_t) &ram[(uintptr_t) (addr & ~0xfff) - (virt & ~0xfff)]; -#else - a = (uintptr_t) (addr & ~0xfff) - (virt & ~0xfff); - uintptr_t target; - - if ((addr & ~0xfff) >= (1 << 30)) - target = (uintptr_t) &ram2[a - (1 << 30)]; - else - target = (uintptr_t) &ram[a]; -#endif - if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { writelookup2[writelookup[c]] = LOOKUP_INV; page_lookup[writelookup[c]] = NULL; @@ -599,10 +570,6 @@ mem_addr_translate(uint32_t addr, uint32_t chunk_start, uint32_t len) void addreadlookup(uint32_t virt, uint32_t phys) { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - uint32_t a; -#endif - if (virt == 0xffffffff) return; @@ -615,16 +582,7 @@ addreadlookup(uint32_t virt, uint32_t phys) readlookup2[readlookup[readlnext]] = LOOKUP_INV; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) readlookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; -#else - a = ((uint32_t) (phys & ~0xfff) - (uint32_t) (virt & ~0xfff)); - - if ((phys & ~0xfff) >= (1 << 30)) - readlookup2[virt >> 12] = (uintptr_t) &ram2[a - (1 << 30)]; - else - readlookup2[virt >> 12] = (uintptr_t) &ram[a]; -#endif readlookup[readlnext++] = virt >> 12; readlnext &= (cachesize - 1); @@ -635,10 +593,6 @@ addreadlookup(uint32_t virt, uint32_t phys) void addwritelookup(uint32_t virt, uint32_t phys) { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - uint32_t a; -#endif - if (virt == 0xffffffff) return; @@ -665,16 +619,8 @@ addwritelookup(uint32_t virt, uint32_t phys) #endif page_lookup[virt >> 12] = &pages[phys >> 12]; } else { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) - writelookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; -#else - a = ((uint32_t) (phys & ~0xfff) - (uint32_t) (virt & ~0xfff)); - if ((phys & ~0xfff) >= (1 << 30)) - writelookup2[virt >> 12] = (uintptr_t) &ram2[a - (1 << 30)]; - else - writelookup2[virt >> 12] = (uintptr_t) &ram[a]; -#endif + writelookup2[virt >> 12] = (uintptr_t) &ram[(uintptr_t) (phys & ~0xFFF) - (uintptr_t) (virt & ~0xfff)]; } writelookup[writelnext++] = virt >> 12; @@ -687,9 +633,7 @@ uint8_t * getpccache(uint32_t a) { uint64_t a64 = (uint64_t) a; -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) uint8_t *p; -#endif uint32_t a2; a2 = a; @@ -710,12 +654,8 @@ getpccache(uint32_t a) cpu_prefetch_cycles = cpu_mem_prefetch_cycles; } -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) p = &_mem_exec[a64 >> MEM_GRANULARITY_BITS][(uintptr_t) (a64 & MEM_GRANULARITY_PAGE) - (uintptr_t) (a2 & ~0xfff)]; return (uint8_t *) (((uintptr_t) p & 0x00000000ffffffffULL) | ((uintptr_t) &_mem_exec[a64 >> MEM_GRANULARITY_BITS][0] & 0xffffffff00000000ULL)); -#else - return &_mem_exec[a64 >> MEM_GRANULARITY_BITS][(uintptr_t) (a64 & MEM_GRANULARITY_PAGE) - (uintptr_t) (a2 & ~0xfff)]; -#endif } mem_log("Bad getpccache %08X%08X\n", (uint32_t) (a64 >> 32), (uint32_t) (a64 & 0xffffffffULL)); @@ -2771,11 +2711,6 @@ mem_init_ram_mapping(mem_mapping_t *mapping, uint32_t base, uint32_t size) void mem_zero(void) { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) - memset(ram2, 0x00, ram2_size + 16); -#endif - memset(ram, 0x00, ram_size + 16); } @@ -2810,55 +2745,17 @@ mem_reset(void) ram = NULL; ram_size = 0; } -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (ram2 != NULL) { - plat_munmap(ram2, ram2_size); - ram2 = NULL; - ram2_size = 0; - } - - if (mem_size > 2097152) - mem_size = 2097152; -#endif m = 1024UL * (size_t) mem_size; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - ram_size = 1 << 30; - ram = (uint8_t *) plat_mmap(ram_size, 0); /* allocate and clear the RAM block of the first 1 GB */ - if (ram == NULL) { - fatal("Failed to allocate primary RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram, 0x00, ram_size); - ram2_size = m - (1 << 30); - /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ - ram2 = (uint8_t *) plat_mmap(ram2_size + 16, 0); /* allocate and clear the RAM block above 1 GB */ - if (ram2 == NULL) { - if (config_changed == 2) - fatal(EMU_NAME " must be restarted for the memory amount change to be applied.\n"); - else - fatal("Failed to allocate secondary RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram2, 0x00, ram2_size + 16); - } else -#endif - { - ram_size = m; - /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ - ram = (uint8_t *) plat_mmap(ram_size + 16, 0); /* allocate and clear the RAM block */ - if (ram == NULL) { - fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); - return; - } - memset(ram, 0x00, ram_size + 16); -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) - ram2 = &(ram[1 << 30]); -#endif + ram_size = m; + /* Allocate 16 extra bytes of RAM to mitigate some dynarec recompiler memory access quirks. */ + ram = (uint8_t *) plat_mmap(ram_size + 16, 0); /* allocate and clear the RAM block */ + if (ram == NULL) { + fatal("Failed to allocate RAM block. Make sure you have enough RAM available.\n"); + return; } + memset(ram, 0x00, ram_size + 16); /* * Allocate the page table based on how much RAM we have. @@ -2905,17 +2802,8 @@ mem_reset(void) if ((c << 12) >= (mem_size << 10)) pages[c].mem = page_ff; else { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - if ((c << 12) < (1 << 30)) - pages[c].mem = &ram[c << 12]; - else - pages[c].mem = &ram2[(c << 12) - (1 << 30)]; - } else - pages[c].mem = &ram[c << 12]; -#else + pages[c].mem = &ram[c << 12]; -#endif } if (c < m) { pages[c].write_b = mem_write_ramb_page; @@ -2951,22 +2839,7 @@ mem_reset(void) else if (cpu_16bitbus && is6117 && mem_size > 65408) mem_init_ram_mapping(&ram_high_mapping, 0x100000, (65408 - 1024) * 1024); else { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (1048576 - 1024) * 1024); - - mem_set_mem_state_both((1 << 30), (mem_size - 1048576) * 1024, - MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_2gb_mapping, (1 << 30), - ((mem_size - 1048576) * 1024), - mem_read_ram_2gb, mem_read_ram_2gbw, mem_read_ram_2gbl, - mem_write_ram, mem_write_ramw, mem_write_raml, - ram2, MEM_MAPPING_INTERNAL, NULL); - } else - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024); -#else - mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024); -#endif + mem_init_ram_mapping(&ram_high_mapping, 0x100000, (mem_size - 1024) * 1024); } } @@ -3005,26 +2878,8 @@ mem_init(void) ram = rom = NULL; ram2 = NULL; pages = NULL; - -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - /* Allocate the lookup tables. */ - page_lookup = (page_t **) malloc((1 << 20) * sizeof(page_t *)); - readlookup2 = malloc((1 << 20) * sizeof(uintptr_t)); - writelookup2 = malloc((1 << 20) * sizeof(uintptr_t)); -#endif } -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -void -mem_free(void) -{ - free(page_lookup); - free(readlookup2); - free(writelookup2); -} -#endif - - static void umc_page_recalc(uint32_t c, uint32_t phys, int set) { @@ -3125,17 +2980,7 @@ mem_remap_top_ex_common(int kb, uint32_t start, int mid) if (sis_mode || ((c << 12) >= (mem_size << 10))) pages[c].mem = page_ff; else { -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) { - if ((c << 12) < (1 << 30)) - pages[c].mem = &ram[c << 12]; - else - pages[c].mem = &ram2[(c << 12) - (1 << 30)]; - } else - pages[c].mem = &ram[c << 12]; -#else pages[c].mem = &ram[c << 12]; -#endif } if (!sis_mode && (c < addr_space_size)) { pages[c].write_b = mem_write_ramb_page; diff --git a/src/mem/row.c b/src/mem/row.c index c3e10841f..572df7f47 100644 --- a/src/mem/row.c +++ b/src/mem/row.c @@ -155,18 +155,9 @@ row_allocate(uint8_t row_id, uint8_t set) mem_mapping_set_exec(&rows[row_id].mapping, rows[row_id].buf + rows[row_id].ram_base); mem_mapping_set_mask(&rows[row_id].mapping, rows[row_id].ram_mask); if ((rows[row_id].host_base == rows[row_id].ram_base) && (rows[row_id].host_size == rows[row_id].ram_size)) { -#if (defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64) mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml, mem_write_ram,mem_write_ramw,mem_write_raml); -#else - if (rows[row_id].buf == ram2) { - mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram_2gb,mem_read_ram_2gbw,mem_read_ram_2gbl, - mem_write_ram,mem_write_ramw,mem_write_raml); - } else { - mem_mapping_set_handler(&rows[row_id].mapping, mem_read_ram,mem_read_ramw,mem_read_raml, - mem_write_ram,mem_write_ramw,mem_write_raml); - } -#endif + } else { mem_mapping_set_handler(&rows[row_id].mapping, row_read, row_readw, row_readl, row_write, row_writew, row_writel); @@ -268,10 +259,6 @@ row_init(const device_t *info) mem_mapping_disable(&ram_low_mapping); mem_mapping_disable(&ram_mid_mapping); mem_mapping_disable(&ram_high_mapping); -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (mem_size > 1048576) - mem_mapping_disable(&ram_2gb_mapping); -#endif for (uint32_t c = 0; c < pages_sz; c++) { pages[c].mem = page_ff; @@ -303,12 +290,7 @@ row_init(const device_t *info) rows[i].ram_size -= rows[i].ram_base; rows[i].buf = ram; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (rows[i].ram_base >= (1 << 30)) { - rows[i].ram_base -= (1 << 30); - rows[i].buf = ram2; - } -#endif + rows[i].ram_mask = rows[i].ram_size - 1; diff --git a/src/mem/smram.c b/src/mem/smram.c index 928760f3a..3cb6679ed 100644 --- a/src/mem/smram.c +++ b/src/mem/smram.c @@ -59,11 +59,6 @@ smram_read(uint32_t addr, void *priv) const smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (new_addr >= (1 << 30)) - return mem_read_ram_2gb(new_addr, priv); - else -#endif if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ram(new_addr, priv); else @@ -76,11 +71,6 @@ smram_readw(uint32_t addr, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (new_addr >= (1 << 30)) - return mem_read_ram_2gbw(new_addr, priv); - else -#endif if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_ramw(new_addr, priv); else @@ -93,11 +83,6 @@ smram_readl(uint32_t addr, void *priv) smram_t *dev = (smram_t *) priv; uint32_t new_addr = addr - dev->host_base + dev->ram_base; -#if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) - if (new_addr >= (1 << 30)) - return mem_read_ram_2gbl(new_addr, priv); - else -#endif if (!use_separate_smram || (new_addr >= 0xa0000)) return mem_read_raml(new_addr, priv); else diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 9c54dccab..38c8053c2 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -48,13 +48,8 @@ #define gs_error_Quit -101 #ifdef _WIN32 -# if (!(defined __amd64__ || defined _M_X64 || defined __aarch64__ || defined _M_ARM64)) -# define PATH_GHOSTSCRIPT_DLL "gsdll32.dll" -# define PATH_GHOSTPCL_DLL "gpcl6dll32.dll" -# else -# define PATH_GHOSTSCRIPT_DLL "gsdll64.dll" -# define PATH_GHOSTPCL_DLL "gpcl6dll64.dll" -# endif +# define PATH_GHOSTSCRIPT_DLL "gsdll64.dll" +# define PATH_GHOSTPCL_DLL "gpcl6dll64.dll" #elif defined __APPLE__ # define PATH_GHOSTSCRIPT_DLL "libgs.dylib" # define PATH_GHOSTPCL_DLL "libgpcl6.9.54.dylib" diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index 240315faa..a0c2aa502 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -614,13 +614,8 @@ c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -# if defined(__amd64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) -# define LIB_NAME_GS "gsdll64.dll" -# define LIB_NAME_GPCL "gpcl6dll64.dll" -# else -# define LIB_NAME_GS "gsdll32.dll" -# define LIB_NAME_GPCL "gpcl6dll32.dll" -# endif +# define LIB_NAME_GS "gsdll64.dll" +# define LIB_NAME_GPCL "gpcl6dll64.dll" # define LIB_NAME_PCAP "Npcap" #else # define LIB_NAME_GS "libgs" From ff32263927d435e634927335a6c340f1439a9d27 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sun, 14 Sep 2025 12:14:45 -0500 Subject: [PATCH 100/138] Clarify SB variable names, correct WSS enable in init --- src/sound/snd_ymf701.c | 70 +++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index 4506688c5..0ce57064f 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -69,12 +69,12 @@ typedef struct ymf701_t { uint8_t wss_config; uint8_t reg_enabled; - uint16_t cur_addr; + uint16_t cur_sb_addr; uint16_t cur_wss_addr; uint16_t cur_mpu401_addr; - int cur_irq; - int cur_dma; + int cur_sb_irq; + int cur_sb_dma; int cur_wss_enabled; int cur_wss_irq; int cur_wss_dma; @@ -168,8 +168,8 @@ ymf701_get_buffer(int32_t *buffer, int len, void *priv) static void ymf701_remove_opl(ymf701_t *ymf701) { - io_removehandler(ymf701->cur_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); - io_removehandler(ymf701->cur_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_removehandler(ymf701->cur_sb_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_removehandler(ymf701->cur_sb_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); io_removehandler(0x0388, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); } @@ -177,8 +177,8 @@ static void ymf701_add_opl(ymf701_t *ymf701) { /* DSP I/O handler is activated in sb_dsp_setaddr */ - io_sethandler(ymf701->cur_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); - io_sethandler(ymf701->cur_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(ymf701->cur_sb_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(ymf701->cur_sb_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); io_sethandler(0x0388, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); } @@ -238,51 +238,51 @@ ymf701_reg_write(uint16_t addr, uint8_t val, void *priv) break; case 0x02: /* SB Config */ ymf701->regs[0x02] = val; - io_removehandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + io_removehandler(ymf701->cur_sb_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); ymf701_remove_opl(ymf701); - ymf701->cur_addr = (val & 0x20) ? 0x240 : 0x220; + ymf701->cur_sb_addr = (val & 0x20) ? 0x240 : 0x220; switch (val & 0x3) { case 0: - ymf701->cur_dma = -1; + ymf701->cur_sb_dma = -1; break; case 1: - ymf701->cur_dma = 0; + ymf701->cur_sb_dma = 0; break; case 2: - ymf701->cur_dma = 1; + ymf701->cur_sb_dma = 1; break; case 3: - ymf701->cur_dma = 3; + ymf701->cur_sb_dma = 3; break; } switch ((val >> 2) & 0x7) { case 0: - ymf701->cur_irq = -1; + ymf701->cur_sb_irq = -1; break; case 1: - ymf701->cur_irq = 5; + ymf701->cur_sb_irq = 5; break; case 2: - ymf701->cur_irq = 7; + ymf701->cur_sb_irq = 7; break; case 3: - ymf701->cur_irq = 9; + ymf701->cur_sb_irq = 9; break; case 4: - ymf701->cur_irq = 10; + ymf701->cur_sb_irq = 10; break; case 5: - ymf701->cur_irq = 11; + ymf701->cur_sb_irq = 11; break; default: break; } - sb_dsp_setaddr(&ymf701->sb->dsp, ymf701->cur_addr); - sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_irq); - sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_dma); + sb_dsp_setaddr(&ymf701->sb->dsp, ymf701->cur_sb_addr); + sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_sb_irq); + sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_sb_dma); ymf701_add_opl(ymf701); - if (ymf701->cur_addr != 0x00) - io_sethandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + if (ymf701->cur_sb_addr != 0x00) + io_sethandler(ymf701->cur_sb_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); break; case 0x03: /* MPU/OPL/Gameport Config */ ymf701->regs[0x03] = val; @@ -388,11 +388,11 @@ ymf701_init(const device_t *info) ymf701->type = info->local & 0xFF; ymf701->cur_wss_addr = 0x530; - ymf701->cur_mode = 0; - ymf701->cur_addr = 0x220; - ymf701->cur_irq = 5; - ymf701->cur_wss_enabled = 0; - ymf701->cur_dma = 1; + ymf701->cur_mode = 1; + ymf701->cur_sb_addr = 0x220; + ymf701->cur_sb_irq = 5; + ymf701->cur_wss_enabled = 1; + ymf701->cur_sb_dma = 1; ymf701->cur_mpu401_irq = 9; ymf701->cur_mpu401_addr = 0x330; ymf701->cur_mpu401_enabled = 1; @@ -426,20 +426,20 @@ ymf701_init(const device_t *info) sb_dsp_set_real_opl(&ymf701->sb->dsp, 1); sb_dsp_init(&ymf701->sb->dsp, SBPRO2_DSP_302, SB_SUBTYPE_DEFAULT, ymf701); - sb_dsp_setaddr(&ymf701->sb->dsp, ymf701->cur_addr); - sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_irq); - sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_dma); + sb_dsp_setaddr(&ymf701->sb->dsp, ymf701->cur_sb_addr); + sb_dsp_setirq(&ymf701->sb->dsp, ymf701->cur_sb_irq); + sb_dsp_setdma8(&ymf701->sb->dsp, ymf701->cur_sb_dma); sb_ct1345_mixer_reset(ymf701->sb); ymf701->sb->opl_mixer = ymf701; ymf701->sb->opl_mix = ymf701_filter_opl; fm_driver_get(FM_YMF262, &ymf701->sb->opl); - io_sethandler(ymf701->cur_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); - io_sethandler(ymf701->cur_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(ymf701->cur_sb_addr + 0, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); + io_sethandler(ymf701->cur_sb_addr + 8, 0x0002, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); io_sethandler(0x0388, 0x0004, ymf701->sb->opl.read, NULL, NULL, ymf701->sb->opl.write, NULL, NULL, ymf701->sb->opl.priv); - io_sethandler(ymf701->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); + io_sethandler(ymf701->cur_sb_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, ymf701->sb); sound_add_handler(ymf701_get_buffer, ymf701); music_add_handler(sb_get_music_buffer_sbpro, ymf701->sb); From 82ad957380d2caa49f27adeb94d588c3d8e57613 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Sep 2025 19:16:55 +0200 Subject: [PATCH 101/138] PCjr: Fix 320x200x4 mode. --- src/video/vid_pcjr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/video/vid_pcjr.c b/src/video/vid_pcjr.c index fd8ef515b..62ce9b61d 100644 --- a/src/video/vid_pcjr.c +++ b/src/video/vid_pcjr.c @@ -467,8 +467,10 @@ vid_render(pcjr_t *pcjr, int line, int ho_s, int ho_d) dat = (pcjr->vram[((pcjr->memaddr << 1) & mask) + offset] << 8) | pcjr->vram[((pcjr->memaddr << 1) & mask) + offset + 1]; pcjr->memaddr++; - for (uint8_t c = 0; c < 8; c++) - buffer32->line[line][ef_x + (c << 1)] = buffer32->line[line][ef_x + (c << 1) + 1] = dat <<= 2; + for (uint8_t c = 0; c < 8; c++) { + buffer32->line[line][ef_x + (c << 1)] = buffer32->line[line][ef_x + (c << 1) + 1] = cols[dat >> 14]; + dat <<= 2; + } } break; case 0x102: /*640x200x2*/ From 39d66f00ef9e2ac201b556687566c9f160b57f73 Mon Sep 17 00:00:00 2001 From: win2kgamer <47463859+win2kgamer@users.noreply.github.com> Date: Sun, 14 Sep 2025 13:45:26 -0500 Subject: [PATCH 102/138] Remove two unused local variables causing a CodeQL failure --- src/sound/snd_ymf701.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index 0ce57064f..001a5622b 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -186,8 +186,6 @@ static void ymf701_reg_write(uint16_t addr, uint8_t val, void *priv) { ymf701_t *ymf701 = (ymf701_t *) priv; - uint16_t idx; - uint8_t old = ymf701->regs[idx]; static uint8_t reg_enable_phase = 0; if (ymf701->reg_enabled) { From da398832c4bbd3058bb78a104dccdbd5038f4af4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Sep 2025 23:30:40 +0200 Subject: [PATCH 103/138] CUBX: Implement CMD-648 disabling via ACPI GPIO, fixes #6169. --- src/acpi.c | 6 +++++- src/disk/hdc.c | 4 ++++ src/disk/hdc_ide_cmd646.c | 24 ++++++++++++++---------- src/include/86box/hdc.h | 1 + 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 6ecca841b..411662e39 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -41,6 +41,7 @@ #include <86box/i2c.h> #include <86box/video.h> #include <86box/smbus.h> +#include <86box/hdc.h> #include <86box/hdc_ide.h> #include <86box/hdc_ide_sff8038i.h> #include <86box/sis_55xx.h> @@ -1219,8 +1220,11 @@ acpi_reg_write_intel(int size, uint16_t addr, uint8_t val, void *priv) case 0x36: case 0x37: /* GPOREG - General Purpose Output Register (IO) */ - if (size == 1) + if (size == 1) { dev->regs.gporeg[addr & 3] = val; + if ((addr == 0x34) && !strcmp(machine_get_internal_name(), "cubx")) + hdc_onboard_enabled = (val & 0x01); + } break; default: acpi_reg_write_common_regs(size, addr, val, priv); diff --git a/src/disk/hdc.c b/src/disk/hdc.c index 135528401..1e0d3f2bb 100644 --- a/src/disk/hdc.c +++ b/src/disk/hdc.c @@ -32,6 +32,8 @@ int hdc_current[HDC_MAX] = { 0, 0 }; +int hdc_onboard_enabled = 1; + #ifdef ENABLE_HDC_LOG int hdc_do_log = ENABLE_HDC_LOG; @@ -114,6 +116,8 @@ hdc_init(void) void hdc_reset(void) { + hdc_onboard_enabled = 1; + for (int i = 0; i < HDC_MAX; i++) { hdc_log("HDC %i: reset(current=%d, internal=%d)\n", i, hdc_current[i], hdc_current[i] == HDC_INTERNAL); diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 7aa920e22..333cd5e30 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -145,6 +145,7 @@ cmd646_ide_handlers(cmd646_t *dev) int first = 0; int reg09 = dev->regs[0x09]; int reg50 = dev->regs[0x50]; + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); if ((dev->local & CMD_TYPE_648) && (dev->local & CMD648_RAID)) { reg09 = 0xff; @@ -180,7 +181,7 @@ cmd646_ide_handlers(cmd646_t *dev) if (dev->local & CMD_TYPE_648) pri_enabled = pri_enabled && (dev->regs[0x51] & 0x04); - if (pri_enabled) + if (dev_enabled && pri_enabled) ide_handlers(first, 1); if (dev->single_channel) @@ -205,7 +206,7 @@ cmd646_ide_handlers(cmd646_t *dev) sff_set_irq_mode(dev->bm[1], irq_mode[1]); cmd646_log("IDE %i: %04X, %04X, %i\n", first + 1, main, side, irq_mode[1]); - if ((dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) + if (dev_enabled && (dev->regs[0x04] & 0x01) && (dev->regs[0x51] & 0x08)) ide_handlers(first + 1, 1); } @@ -213,9 +214,10 @@ static void cmd646_ide_bm_handlers(cmd646_t *dev) { uint16_t base = (dev->regs[0x20] & 0xf0) | (dev->regs[0x21] << 8); + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); - sff_bus_master_handler(dev->bm[0], (dev->regs[0x04] & 1), base); - sff_bus_master_handler(dev->bm[1], (dev->regs[0x04] & 1), base + 8); + sff_bus_master_handler(dev->bm[0], dev_enabled && (dev->regs[0x04] & 1), base); + sff_bus_master_handler(dev->bm[1], dev_enabled && (dev->regs[0x04] & 1), base + 8); } uint8_t @@ -296,15 +298,16 @@ cmd646_bios_handler(cmd646_t *dev) static void cmd646_pci_write(int func, int addr, uint8_t val, void *priv) { - cmd646_t *dev = (cmd646_t *) priv; - int reg50 = dev->regs[0x50]; + cmd646_t *dev = (cmd646_t *) priv; + int reg50 = dev->regs[0x50]; + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); if ((dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04) && (dev->regs[0x0b] == 0x01)) reg50 |= 0x40; cmd646_log("[%04X:%08X] (%08X) cmd646_pci_write(%i, %02X, %02X)\n", CS, cpu_state.pc, ESI, func, addr, val); - if (func == 0x00) + if (dev_enabled && (func == 0x00)) switch (addr) { case 0x04: if (dev->has_bios) @@ -480,10 +483,11 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) static uint8_t cmd646_pci_read(int func, int addr, void *priv) { - cmd646_t *dev = (cmd646_t *) priv; - uint8_t ret = 0xff; + cmd646_t *dev = (cmd646_t *) priv; + uint8_t ret = 0xff; + int dev_enabled = (hdc_onboard_enabled || !(dev->local & CMD64X_ONBOARD)); - if (func == 0x00) { + if (dev_enabled && (func == 0x00)) { ret = dev->regs[addr]; if ((addr == 0x09) && (dev->local & CMD_TYPE_648) && (dev->regs[0x0a] == 0x04)) diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 26fed9b0a..214ed84e5 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -30,6 +30,7 @@ #define HDC_MAX 4 extern int hdc_current[HDC_MAX]; +extern int hdc_onboard_enabled; extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */ extern const device_t st506_xt_wdxt_gen_device; /* st506_xt_wdxt_gen */ From 9702e28e5c3f2fd8275c196c7ed38f4900d9e130 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 Sep 2025 23:47:43 +0200 Subject: [PATCH 104/138] YMF-701: Removed an unused variable. --- src/sound/snd_ymf701.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sound/snd_ymf701.c b/src/sound/snd_ymf701.c index 001a5622b..ff2f9f78a 100644 --- a/src/sound/snd_ymf701.c +++ b/src/sound/snd_ymf701.c @@ -185,8 +185,7 @@ ymf701_add_opl(ymf701_t *ymf701) static void ymf701_reg_write(uint16_t addr, uint8_t val, void *priv) { - ymf701_t *ymf701 = (ymf701_t *) priv; - static uint8_t reg_enable_phase = 0; + ymf701_t *ymf701 = (ymf701_t *) priv; if (ymf701->reg_enabled) { ymf701_log(ymf701->log, "Write with reg access enabled:\n"); From 6de981363e7409acf3a51a374bd6880f93816feb Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 2 Dec 2022 14:03:30 -0500 Subject: [PATCH 105/138] Use SQXTUN instead of UQXTN in PACKUSWB on arm64 --- src/codegen_new/codegen_backend_arm64_ops.c | 7 +++++++ src/codegen_new/codegen_backend_arm64_ops.h | 1 + src/codegen_new/codegen_backend_arm64_uops.c | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 915cae93d..21f0df34d 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -180,6 +180,7 @@ # define OPCODE_SQSUB_V8B (0x0e202c00) # define OPCODE_SQSUB_V4H (0x0e602c00) # define OPCODE_SQXTN_V8B_8H (0x0e214800) +# define OPCODE_SQXTUN_V8B_8H (0x7e212800) # define OPCODE_SQXTN_V4H_4S (0x0e614800) # define OPCODE_SHL_VD (0x0f005400) # define OPCODE_SHL_VQ (0x4f005400) @@ -1225,6 +1226,12 @@ host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } + +void host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_addlong(block, OPCODE_SQXTUN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); +} + void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index df751b4aa..084bbb404 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -184,6 +184,7 @@ void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); +void host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 2bb6281ff..f6038f71f 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -1480,8 +1480,8 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_SQXTUN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTUN_V8B_8H(block, dest_reg, dest_reg); host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); From 1488097c7bd633678d16678fa1bbe403ee2c7fc1 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 2 Dec 2022 14:05:18 -0500 Subject: [PATCH 106/138] Reenable MMX opcodes on ARM new dynarec --- src/codegen_new/codegen_ops.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index bb7d1f3ee..039e0877a 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -86,13 +86,8 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, -#endif /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -100,15 +95,9 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -#endif /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -119,13 +108,8 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, -#endif /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -133,15 +117,9 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -#endif // clang-format on }; From ffed72f8233ab952883cd71beab4899e6f901684 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Sep 2025 11:11:26 +0000 Subject: [PATCH 107/138] NDR (AArch64): Fix `ismmx` value assignment --- src/codegen_new/codegen_backend_arm64_ops.c | 7 ++++--- src/codegen_new/codegen_backend_arm64_uops.c | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 21f0df34d..afe00fe4d 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -226,11 +226,11 @@ # define IMM_LOGICAL(imm) ((imm) << 10) -# define BIT_TBxZ(bit) ((((bit) &0x1f) << 19) | (((bit) &0x20) ? (1 << 31) : 0)) +# define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) # define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) # define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) &0x1fffff) >> 2) << 5)) +# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) # define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) # define OFFSET12_B(offset) (offset << 10) @@ -1227,7 +1227,8 @@ host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SQXTUN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index f6038f71f..4c00cbed2 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -801,7 +801,8 @@ codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); - host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 1); + host_arm64_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); return 0; } From 15a3df6135ef07218c141c2d99526cb072e10d5a Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Sep 2025 16:18:19 +0000 Subject: [PATCH 108/138] Fix PACK* recompiled instructions on ARM64 --- src/codegen_new/codegen_backend_arm64_ops.c | 6 ++++++ src/codegen_new/codegen_backend_arm64_ops.h | 1 + src/codegen_new/codegen_backend_arm64_uops.c | 15 ++++++--------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index afe00fe4d..7f0518f04 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -208,6 +208,7 @@ # define OPCODE_ZIP1_V8B (0x0e003800) # define OPCODE_ZIP1_V4H (0x0e403800) # define OPCODE_ZIP1_V2S (0x0e803800) +# define OPCODE_ZIP1_V2D (0x4ec03800) # define OPCODE_ZIP2_V8B (0x0e007800) # define OPCODE_ZIP2_V4H (0x0e407800) # define OPCODE_ZIP2_V2S (0x0e807800) @@ -1483,6 +1484,11 @@ host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_re codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } void +host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +{ + codegen_addlong(block, OPCODE_ZIP1_V2D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); +} +void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index 084bbb404..152ab6793 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -244,6 +244,7 @@ void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); +void host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 4c00cbed2..925e6517b 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -1449,9 +1449,8 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) 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_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_ZIP1_V2D(block, REG_V_TEMP, dest_reg, src_reg_b); + host_arm64_SQXTN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1466,9 +1465,8 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) 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_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_ZIP1_V2D(block, REG_V_TEMP, dest_reg, src_reg_b); + host_arm64_SQXTN_V4H_4S(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1481,9 +1479,8 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_SQXTUN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTUN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_ZIP1_V2D(block, REG_V_TEMP, dest_reg, src_reg_b); + host_arm64_SQXTUN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); From 62296072775381145c2e3627d8af057f0733be20 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Sep 2025 23:42:14 +0600 Subject: [PATCH 109/138] Temp MMX debugging logs --- src/codegen_new/codegen.c | 6 ++++++ src/codegen_new/codegen_ops_mmx_arith.c | 3 +++ src/codegen_new/codegen_ops_mmx_cmp.c | 3 +++ src/codegen_new/codegen_ops_mmx_loadstore.c | 6 ++++++ src/codegen_new/codegen_ops_mmx_logic.c | 5 +++++ src/codegen_new/codegen_ops_mmx_pack.c | 2 ++ src/codegen_new/codegen_ops_mmx_shift.c | 4 ++++ 7 files changed, 29 insertions(+) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 875dd72ca..57d8c4dbc 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -30,6 +30,12 @@ static struct { int TOP; } codegen_instructions[MAX_INSTRUCTION_COUNT]; +void +codegen_print_mmx(void) +{ + pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX\n", cpu_state.MM[0], cpu_state.MM[1], cpu_state.MM[2], cpu_state.MM[3], cpu_state.MM[4], cpu_state.MM[5], cpu_state.MM[6], cpu_state.MM[7]); +} + int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) { diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index f01d64273..3ac6eb0d6 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -16,6 +16,8 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" +extern void codegen_print_mmx(void); + #define ropParith(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -37,6 +39,7 @@ uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index cf0cededb..865522f09 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -16,6 +16,8 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" +extern void codegen_print_mmx(void); + #define ropPcmp(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -37,6 +39,7 @@ uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index 9d37228ec..c0148781e 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -16,6 +16,8 @@ #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_helpers.h" +extern void codegen_print_mmx(void); + uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -36,6 +38,7 @@ ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -62,6 +65,7 @@ ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -84,6 +88,7 @@ ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -107,5 +112,6 @@ ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index dd50b486e..36d957c5e 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -16,6 +16,7 @@ #include "codegen_ops_mmx_logic.h" #include "codegen_ops_helpers.h" +extern void codegen_print_mmx(void); uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -36,6 +37,7 @@ ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -58,6 +60,7 @@ ropPANDN(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -80,6 +83,7 @@ ropPOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetch uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -102,5 +106,6 @@ ropPXOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index c62aa10d0..69ec3ce3a 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -16,6 +16,7 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" +extern void codegen_print_mmx(void); #define ropPpack(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -37,6 +38,7 @@ uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index b812a9bb2..b1f41d1bb 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -16,6 +16,7 @@ #include "codegen_ops_mmx_shift.h" #include "codegen_ops_helpers.h" +extern void codegen_print_mmx(void); uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { @@ -39,6 +40,7 @@ ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } + uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; } @@ -65,6 +67,7 @@ ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } + uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; } @@ -91,6 +94,7 @@ ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } + uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; } From 4735998b8a62631907157c02ded214d9fcc0fd52 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Sep 2025 23:46:00 +0600 Subject: [PATCH 110/138] Warning fixes --- src/codegen_new/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 57d8c4dbc..adc0d30d9 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -33,7 +33,7 @@ static struct { void codegen_print_mmx(void) { - pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX\n", cpu_state.MM[0], cpu_state.MM[1], cpu_state.MM[2], cpu_state.MM[3], cpu_state.MM[4], cpu_state.MM[5], cpu_state.MM[6], cpu_state.MM[7]); + pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q, cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); } int From 97ab7a8ce8c715213b940fc0f9a675fcbeccc71d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Sun, 14 Sep 2025 23:47:18 +0600 Subject: [PATCH 111/138] More warning fixes --- src/codegen_new/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index adc0d30d9..0b3449500 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -33,7 +33,7 @@ static struct { void codegen_print_mmx(void) { - pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q, cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); + pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX\n", (unsigned long long)cpu_state.MM[0].q, (unsigned long long)cpu_state.MM[1].q, (unsigned long long)cpu_state.MM[2].q, (unsigned long long)cpu_state.MM[3].q, (unsigned long long)cpu_state.MM[4].q, (unsigned long long)cpu_state.MM[5].q, (unsigned long long)cpu_state.MM[6].q, (unsigned long long)cpu_state.MM[7].q); } int From d824fc36df1ae05d5a114bdfe46a7b835a7ac2c1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 12:34:34 +0600 Subject: [PATCH 112/138] Yet more logging --- src/codegen_new/codegen.c | 4 ++-- src/codegen_new/codegen_backend_arm64_uops.c | 8 ++++---- src/codegen_new/codegen_backend_x86-64_uops.c | 12 ++++++------ src/codegen_new/codegen_ir_defs.h | 4 ++-- src/codegen_new/codegen_ops_mmx_arith.c | 3 ++- src/codegen_new/codegen_ops_mmx_cmp.c | 3 ++- src/codegen_new/codegen_ops_mmx_loadstore.c | 6 +++++- src/codegen_new/codegen_ops_mmx_logic.c | 6 +++++- src/codegen_new/codegen_ops_mmx_pack.c | 3 ++- src/codegen_new/codegen_ops_mmx_shift.c | 5 ++++- 10 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 0b3449500..8dfb9b386 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -31,9 +31,9 @@ static struct { } codegen_instructions[MAX_INSTRUCTION_COUNT]; void -codegen_print_mmx(void) +codegen_print_mmx(const char* str) { - pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX\n", (unsigned long long)cpu_state.MM[0].q, (unsigned long long)cpu_state.MM[1].q, (unsigned long long)cpu_state.MM[2].q, (unsigned long long)cpu_state.MM[3].q, (unsigned long long)cpu_state.MM[4].q, (unsigned long long)cpu_state.MM[5].q, (unsigned long long)cpu_state.MM[6].q, (unsigned long long)cpu_state.MM[7].q); + pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX (%s)\n", (unsigned long long)cpu_state.MM[0].q, (unsigned long long)cpu_state.MM[1].q, (unsigned long long)cpu_state.MM[2].q, (unsigned long long)cpu_state.MM[3].q, (unsigned long long)cpu_state.MM[4].q, (unsigned long long)cpu_state.MM[5].q, (unsigned long long)cpu_state.MM[6].q, (unsigned long long)cpu_state.MM[7].q, str); } int diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 925e6517b..c09b74fca 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -850,28 +850,28 @@ codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG0, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG1, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG2, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + host_arm64_MOVX_IMM(block, REG_ARG3, uop->imm_data); return 0; } diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 356c8bcde..6b206d5b5 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -220,9 +220,9 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); # else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); # endif host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); @@ -906,9 +906,9 @@ static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); # else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); # endif return 0; } @@ -916,9 +916,9 @@ static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RDX, uop->imm_data); # else - host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOV64_REG_IMM(block, REG_RSI, uop->imm_data); # endif return 0; } diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 60f7badea..bfc19373b 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -336,7 +336,7 @@ typedef struct uop_t { ir_reg_t src_reg_a; ir_reg_t src_reg_b; ir_reg_t src_reg_c; - uint32_t imm_data; + uintptr_t imm_data; void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; @@ -601,7 +601,7 @@ uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_re } static inline void -uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uintptr_t imm) { uop_t *uop = uop_alloc(ir, uop_type); diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index 3ac6eb0d6..4f8a5d91c 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(void); +extern void codegen_print_mmx(const char* str); #define ropParith(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ @@ -39,6 +39,7 @@ extern void codegen_print_mmx(void); uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index 865522f09..d28c9197c 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(void); +extern void codegen_print_mmx(const char* str); #define ropPcmp(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ @@ -39,6 +39,7 @@ extern void codegen_print_mmx(void); uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index c0148781e..d7ff5b355 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(void); +extern void codegen_print_mmx(const char* str); uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -38,6 +38,7 @@ ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -65,6 +66,7 @@ ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -88,6 +90,7 @@ ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -112,6 +115,7 @@ ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 36d957c5e..e8e092fad 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_logic.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(void); +extern void codegen_print_mmx(const char* str); uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -37,6 +37,7 @@ ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -60,6 +61,7 @@ ropPANDN(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -83,6 +85,7 @@ ropPOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetch uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -106,6 +109,7 @@ ropPXOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 69ec3ce3a..5c01c7e92 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(void); +extern void codegen_print_mmx(const char* str); #define ropPpack(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -38,6 +38,7 @@ extern void codegen_print_mmx(void); uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index b1f41d1bb..42aea4f1c 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_shift.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(void); +extern void codegen_print_mmx(const char* str); uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { @@ -40,6 +40,7 @@ ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; @@ -67,6 +68,7 @@ ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; @@ -94,6 +96,7 @@ ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } + uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; From 1d8877fba79e1eec6958e96c646cb0872541a65b Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 09:19:40 +0000 Subject: [PATCH 113/138] Progress on ARM64 MMX opcodes --- src/codegen_new/codegen.c | 4 ++-- src/codegen_new/codegen_backend_arm64_ops.c | 12 +++++++++++- src/codegen_new/codegen_backend_arm64_ops.h | 1 + src/codegen_new/codegen_backend_arm64_uops.c | 13 ++++++++++--- src/codegen_new/codegen_ops_mmx_arith.c | 3 ++- src/codegen_new/codegen_ops_mmx_cmp.c | 3 ++- src/codegen_new/codegen_ops_mmx_loadstore.c | 6 +++++- src/codegen_new/codegen_ops_mmx_logic.c | 3 ++- src/codegen_new/codegen_ops_mmx_pack.c | 3 ++- src/codegen_new/codegen_ops_mmx_shift.c | 5 ++++- 10 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 8dfb9b386..48d2afad9 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -31,9 +31,9 @@ static struct { } codegen_instructions[MAX_INSTRUCTION_COUNT]; void -codegen_print_mmx(const char* str) +codegen_print_mmx(const char* str, uint32_t fetchdat) { - pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX (%s)\n", (unsigned long long)cpu_state.MM[0].q, (unsigned long long)cpu_state.MM[1].q, (unsigned long long)cpu_state.MM[2].q, (unsigned long long)cpu_state.MM[3].q, (unsigned long long)cpu_state.MM[4].q, (unsigned long long)cpu_state.MM[5].q, (unsigned long long)cpu_state.MM[6].q, (unsigned long long)cpu_state.MM[7].q, str); + pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX (%s, fetchdat 0x%08X)\n", (unsigned long long)cpu_state.MM[0].q, (unsigned long long)cpu_state.MM[1].q, (unsigned long long)cpu_state.MM[2].q, (unsigned long long)cpu_state.MM[3].q, (unsigned long long)cpu_state.MM[4].q, (unsigned long long)cpu_state.MM[5].q, (unsigned long long)cpu_state.MM[6].q, (unsigned long long)cpu_state.MM[7].q, str, fetchdat); } int diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 7f0518f04..9d5806edf 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -102,6 +102,10 @@ # define OPCODE_SUB_LSR (0x25a << 21) # define OPCODE_SUBX_LSL (0x658 << 21) +# define OPCODE_INS_B (0x6e010400) +# define OPCODE_INS_H (0x6e020400) +# define OPCODE_INS_S (0x6e040400) +# define OPCODE_INS_D (0x6e080400) # define OPCODE_ADD_V8B (0x0e208400) # define OPCODE_ADD_V4H (0x0e608400) # define OPCODE_ADD_V2S (0x0ea08400) @@ -180,7 +184,7 @@ # define OPCODE_SQSUB_V8B (0x0e202c00) # define OPCODE_SQSUB_V4H (0x0e602c00) # define OPCODE_SQXTN_V8B_8H (0x0e214800) -# define OPCODE_SQXTUN_V8B_8H (0x7e212800) +# define OPCODE_SQXTUN_V8B_8H (0x2e212800) # define OPCODE_SQXTN_V4H_4S (0x0e614800) # define OPCODE_SHL_VD (0x0f005400) # define OPCODE_SHL_VQ (0x4f005400) @@ -718,6 +722,12 @@ host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } +void +host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index) +{ + codegen_addlong(block, OPCODE_INS_D | Rd(dst_reg) | Rn(src_reg) | ((dst_index & 1) << 20) | ((src_index & 1) << 14)); +} + void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index 152ab6793..129c2b2a3 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -72,6 +72,7 @@ void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element); +void host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index); void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index c09b74fca..c4923387c 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -1449,7 +1449,8 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) 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_arm64_ZIP1_V2D(block, REG_V_TEMP, dest_reg, src_reg_b); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); host_arm64_SQXTN_V8B_8H(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1465,7 +1466,8 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) 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_arm64_ZIP1_V2D(block, REG_V_TEMP, dest_reg, src_reg_b); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); host_arm64_SQXTN_V4H_4S(block, dest_reg, REG_V_TEMP); } else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1479,8 +1481,13 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_ZIP1_V2D(block, REG_V_TEMP, dest_reg, src_reg_b); + host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); + host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); host_arm64_SQXTUN_V8B_8H(block, dest_reg, REG_V_TEMP); + //host_arm64_ADD_V4H(block, dest_reg, dest_reg, src_reg_b); + //host_arm64_SQXTUN_V8B_8H(block, REG_V_TEMP, src_reg_b); + //host_arm64_SQXTUN_V8B_8H(block, dest_reg, dest_reg); + //host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index 4f8a5d91c..4688f3e2b 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str); +extern void codegen_print_mmx(const char* str, uint32_t fetchdat); #define ropParith(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ @@ -40,6 +40,7 @@ extern void codegen_print_mmx(const char* str); } \ \ uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); \ uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index d28c9197c..09006cae7 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str); +extern void codegen_print_mmx(const char* str, uint32_t fetchdat); #define ropPcmp(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ @@ -40,6 +40,7 @@ extern void codegen_print_mmx(const char* str); } \ \ uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); \ uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index d7ff5b355..267e7312a 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str); +extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) @@ -39,6 +39,7 @@ ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -67,6 +68,7 @@ ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -91,6 +93,7 @@ ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -116,6 +119,7 @@ ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index e8e092fad..24dbd167e 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_logic.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str); +extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { @@ -110,6 +110,7 @@ ropPXOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 5c01c7e92..86cd99e0a 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str); +extern void codegen_print_mmx(const char* str, uint32_t fetchdat); #define ropPpack(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -39,6 +39,7 @@ extern void codegen_print_mmx(const char* str); } \ \ uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); \ uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index 42aea4f1c..e6c6da410 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -16,7 +16,7 @@ #include "codegen_ops_mmx_shift.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str); +extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { @@ -41,6 +41,7 @@ ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; @@ -69,6 +70,7 @@ ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; @@ -97,6 +99,7 @@ ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t } uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); + uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; From fe28a8bb627326ace5b2a8804c857fa1a53c3077 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 11:47:03 +0000 Subject: [PATCH 114/138] Disable unrolling for now --- src/codegen_new/codegen_ops_helpers.h | 1 + src/codegen_new/codegen_ops_mmx_arith.c | 5 ----- src/codegen_new/codegen_ops_mmx_cmp.c | 5 ----- src/codegen_new/codegen_ops_mmx_loadstore.c | 12 ------------ src/codegen_new/codegen_ops_mmx_logic.c | 9 --------- src/codegen_new/codegen_ops_mmx_pack.c | 4 ---- src/codegen_new/codegen_ops_mmx_shift.c | 10 ---------- src/codegen_new/codegen_reg.c | 2 +- 8 files changed, 2 insertions(+), 46 deletions(-) diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 92b721099..0128e15ae 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,6 +114,7 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { + return 0; if (block->flags & CODEBLOCK_BYTE_MASK) return 0; diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index 4688f3e2b..f01d64273 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -16,8 +16,6 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str, uint32_t fetchdat); - #define ropParith(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -39,9 +37,6 @@ extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); \ - uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index 09006cae7..cf0cededb 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -16,8 +16,6 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str, uint32_t fetchdat); - #define ropPcmp(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -39,9 +37,6 @@ extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); \ - uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index 267e7312a..e46af7e44 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -38,9 +38,6 @@ ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -67,9 +64,6 @@ ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -92,9 +86,6 @@ ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } @@ -118,8 +109,5 @@ ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 24dbd167e..dec8d8c04 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -37,8 +37,6 @@ ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -61,8 +59,6 @@ ropPANDN(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fet uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -85,8 +81,6 @@ ropPOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetch uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } uint32_t @@ -109,8 +103,5 @@ ropPXOR(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetc uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 86cd99e0a..c62aa10d0 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -16,7 +16,6 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str, uint32_t fetchdat); #define ropPpack(func) \ uint32_t rop##func(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), \ uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ @@ -38,9 +37,6 @@ extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ } \ \ - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); \ - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); \ - uop_CALL_FUNC(ir, codegen_print_mmx); \ return op_pc + 1; \ } diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index e6c6da410..b812a9bb2 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -16,7 +16,6 @@ #include "codegen_ops_mmx_shift.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, UNUSED(uint32_t op_32), uint32_t op_pc) { @@ -40,9 +39,6 @@ ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; } @@ -69,9 +65,6 @@ ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; } @@ -98,9 +91,6 @@ ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t return 0; } - uop_LOAD_FUNC_ARG_IMM(ir, 0, (uintptr_t)__func__); - uop_LOAD_FUNC_ARG_IMM(ir, 1, fetchdat); - uop_CALL_FUNC(ir, codegen_print_mmx); codegen_mark_code_present(block, cs + op_pc + 1, 1); return op_pc + 2; } diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index f91377df8..b678bd6ac 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -201,7 +201,7 @@ static const uint8_t native_requested_sizes[9][8] = [REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, [REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, - [REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1 + [REG_POINTER][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1 }; void From c3a6e826b4e3adf8264186f68afc4a0a54815387 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 15 Sep 2025 17:48:24 +0200 Subject: [PATCH 115/138] S3 928 and icd2061 mode rework (September 15th, 2025) The rework resolves around implementing the clock multiplier and multiplexing rate of the bt485 ramdac alongside existing additional flags for eventual fixes (like cr31 bit 1) as well as the true color bypass (for 16-bit and true color modes). These, together, allow proper rendering of the generic VESA S3 drivers alongside non-VESA ELSA OEM drivers on various guests. --- src/include/86box/vid_clockgen_icd2061.h | 38 ++ src/include/86box/vid_svga.h | 5 +- src/video/clockgen/vid_clockgen_icd2061.c | 19 +- src/video/ramdac/vid_ramdac_bt48x.c | 21 +- src/video/ramdac/vid_ramdac_sc1502x.c | 4 + src/video/vid_et4000w32.c | 2 + src/video/vid_s3.c | 513 ++++++++++------------ 7 files changed, 301 insertions(+), 301 deletions(-) create mode 100644 src/include/86box/vid_clockgen_icd2061.h diff --git a/src/include/86box/vid_clockgen_icd2061.h b/src/include/86box/vid_clockgen_icd2061.h new file mode 100644 index 000000000..78734a347 --- /dev/null +++ b/src/include/86box/vid_clockgen_icd2061.h @@ -0,0 +1,38 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running 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. + * + * ICD2061 clock generator emulation. + * Also emulates the ICS9161 which is the same as the ICD2016, + * but without the need for tuning (which is irrelevant in + * emulation anyway). + * + * Used by ET4000w32/p (Diamond Stealth 32) and the S3 + * Vision964 family. + * + * + * + * Authors: Miran Grca, + * + * Copyright 2016-2018 Miran Grca. + */ +#ifndef VIDEO_CLOCKGEN_ICD2061_H +#define VIDEO_CLOCKGEN_ICD2061_H + +typedef struct icd2061_t { + float freq[3]; + float ref_clock; + + int count; + int bit_count; + int unlocked; + int state; + uint32_t data; + uint32_t ctrl; +} icd2061_t; + +#endif // VIDEO_CLOCKGEN_ICD2061_H diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index cbd6c511a..66ed2affe 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -142,6 +142,9 @@ typedef struct svga_t { int start_retrace_latch; int vga_mode; int half_pixel; + int clock_multiplier; + int true_color_bypass; + int multiplexing_rate; /*The three variables below allow us to implement memory maps like that seen on a 1MB Trio64 : 0MB-1MB - VRAM @@ -450,7 +453,7 @@ extern void ibm_rgb528_ramdac_set_ref_clock(void *priv, svga_t *svga, float r extern void icd2061_write(void *priv, int val); extern float icd2061_getclock(int clock, void *priv); -extern void icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock); +extern void icd2061_set_ref_clock(void *priv, float ref_clock); /* The code is the same, the #define's are so that the correct name can be used. */ # define ics9161_write icd2061_write diff --git a/src/video/clockgen/vid_clockgen_icd2061.c b/src/video/clockgen/vid_clockgen_icd2061.c index f1925e769..a7f0286f2 100644 --- a/src/video/clockgen/vid_clockgen_icd2061.c +++ b/src/video/clockgen/vid_clockgen_icd2061.c @@ -33,20 +33,9 @@ #include <86box/timer.h> #include <86box/video.h> #include <86box/vid_svga.h> +#include <86box/vid_clockgen_icd2061.h> #include <86box/plat_unused.h> -typedef struct icd2061_t { - float freq[3]; - float ref_clock; - - int count; - int bit_count; - int unlocked; - int state; - uint32_t data; - uint32_t ctrl; -} icd2061_t; - #ifdef ENABLE_ICD2061_LOG int icd2061_do_log = ENABLE_ICD2061_LOG; @@ -155,14 +144,12 @@ icd2061_getclock(int clock, void *priv) } void -icd2061_set_ref_clock(void *priv, svga_t *svga, float ref_clock) +icd2061_set_ref_clock(void *priv, float ref_clock) { icd2061_t *icd2061 = (icd2061_t *) priv; - if (icd2061) + if (icd2061 != NULL) icd2061->ref_clock = ref_clock; - - svga_recalctimings(svga); } static void * diff --git a/src/video/ramdac/vid_ramdac_bt48x.c b/src/video/ramdac/vid_ramdac_bt48x.c index 64112e089..7ae96dfbd 100644 --- a/src/video/ramdac/vid_ramdac_bt48x.c +++ b/src/video/ramdac/vid_ramdac_bt48x.c @@ -101,7 +101,7 @@ bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *priv, svga_ switch (rs) { case 0x00: /* Palette Write Index Register (RS value = 0000) */ case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */ - case 0x03: + case 0x03: /* Palette Read Index Register (RS value = 0011) */ case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */ svga->dac_pos = 0; svga->dac_status = addr & 0x03; @@ -362,14 +362,21 @@ bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *priv, svga_t *svga) void bt48x_recalctimings(void *priv, svga_t *svga) { - const bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; + bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv; - svga->interlace = ramdac->cmd_r2 & 0x08; - if (ramdac->cmd_r3 & 0x08) { - svga->hdisp <<= 1; /* x2 clock multiplier */ - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; + svga->interlace = !!(ramdac->cmd_r2 & 0x08); + svga->clock_multiplier = 0; + svga->multiplexing_rate = 0; + svga->true_color_bypass = 0; + if (ramdac->cmd_r3 & 0x08) { /* x2 clock multiplier */ + //pclog("2x multiplier.\n"); + svga->clock_multiplier = 1; } + svga->multiplexing_rate = (ramdac->cmd_r1 & 0x60) >> 5; + if (svga->bpp >= 15) + svga->true_color_bypass = !!(ramdac->cmd_r1 & 0x10); + + //pclog("CR0=%02x, CR1=%02x, CR2=%02x.\n", ramdac->cmd_r0, ramdac->cmd_r1, ramdac->cmd_r2); } void diff --git a/src/video/ramdac/vid_ramdac_sc1502x.c b/src/video/ramdac/vid_ramdac_sc1502x.c index 4fc603ee9..972e0d895 100644 --- a/src/video/ramdac/vid_ramdac_sc1502x.c +++ b/src/video/ramdac/vid_ramdac_sc1502x.c @@ -44,6 +44,7 @@ static void sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga) { int oldbpp = svga->bpp; + //pclog("BPP Val=%02x, truecolortype=%02x.\n", ramdac->ctrl, ramdac->regs[0x10] & 0x01); if (ramdac->ctrl & 0x80) { if (ramdac->ctrl & 0x40) { svga->bpp = 16; @@ -60,6 +61,7 @@ sc1502x_ramdac_bpp(sc1502x_ramdac_t *ramdac, svga_t *svga) } else svga->bpp = 8; } + //pclog("SVGA BPP=%d.\n", svga->bpp); if (oldbpp != svga->bpp) svga_recalctimings(svga); } @@ -135,9 +137,11 @@ sc1502x_rs2_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *priv, svga_t * uint8_t rs = (addr & 0x03); rs |= ((!!rs2) << 2); + //pclog("RS=%02x, Write=%02x.\n", rs, val); switch (rs) { case 0x00: if (ramdac->ctrl & 0x10) { + //pclog("RAMDAC IDX=%02x, Write=%02x.\n", ramdac->idx, val); switch (ramdac->idx) { case 8: ramdac->regs[8] = val; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index c1021e905..3f661eabd 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2845,6 +2845,8 @@ et4000w32p_init(const device_t *info) et4000->svga.ramdac = device_add(&stg_ramdac_device); et4000->svga.clock_gen = device_add(&icd2061_device); et4000->svga.getclock = icd2061_getclock; + icd2061_set_ref_clock(et4000->svga.ramdac, 14318184.0f); + svga_recalctimings(&et4000->svga); break; default: diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 53f75365f..e3176381a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -16,6 +16,7 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ +#include #include #include #include @@ -3000,6 +3001,8 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if (svga->getclock == icd2061_getclock) { if (((val >> 2) & 3) != 3) icd2061_write(svga->clock_gen, (val >> 2) & 3); + else + icd2061_write(svga->clock_gen, svga->crtc[0x42] & 0x0f); } break; @@ -3026,7 +3029,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 0x08) + svga->chain2_write = !(val & 4); + svga->chain4 = (svga->chain4 & ~8) | (val & 8); + if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; @@ -3212,7 +3217,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); if ((s3->chip >= S3_TRIO32) && (svga->bpp == 32)) svga->hwcursor.x <<= 1; - else if ((s3->chip >= S3_86C928 && s3->chip <= S3_86C805) && ((svga->bpp == 15) || (svga->bpp == 16))) { + else if ((s3->chip >= S3_86C928) && (s3->chip <= S3_86C805) && ((svga->bpp == 15) || (svga->bpp == 16))) { if ((s3->card_type == S3_MIROCRYSTAL10SD_805) && !(svga->crtc[0x45] & 0x04) && (svga->bpp == 16)) svga->hwcursor.x >>= 2; else @@ -3787,7 +3792,6 @@ s3_recalctimings(svga_t *svga) case 0xc0: s3->width = 1280; break; - default: break; } @@ -3823,112 +3827,51 @@ s3_recalctimings(svga_t *svga) if ((svga->crtc[0x3a] & 0x10) && !svga->lowres) { s3_log("BPP=%d, pitch=%d, width=%02x, double?=%x, 16bit?=%d, highres?=%d, " - "attr=%02x, hdisp=%d.\n", svga->bpp, s3->width, svga->crtc[0x50], - svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 4, - svga->attrregs[0x10] & 0x40, svga->hdisp); + "attr=%02x, hdisp=%d, dotsperclock=%x, clksel=%x, clockmultiplier=%d, multiplexingrate=%d.\n", svga->bpp, s3->width, svga->crtc[0x50], + svga->crtc[0x31] & 0x02, s3->color_16bit, s3->accel.advfunc_cntl & 0x04, + svga->attrregs[0x10] & 0x40, svga->hdisp, svga->dots_per_clock, clk_sel, svga->clock_multiplier, svga->multiplexing_rate); switch (svga->bpp) { case 8: svga->render = svga_render_8bpp_highres; switch (s3->chip) { case S3_86C928: - switch (s3->card_type) { - case S3_METHEUS_86C928: - s3_log("928 8bpp: ClockSel=%02x, width=%d, hdisp=%d, dotsperclock=%d.\n", clk_sel, s3->width, svga->hdisp, svga->dots_per_clock); - switch (s3->width) { - case 1280: /*Account for the 1280x1024 resolution*/ - switch (svga->hdisp) { - case 320: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 640: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) { + if (svga->multiplexing_rate == 2) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + } else { + if (!svga->clock_multiplier) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; - break; - default: - break; + } } - break; - case 2048: /*Account for the 1280x1024 resolution*/ - switch (svga->hdisp) { - case 320: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 640: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; + svga->clock *= 2.0; + } else { + if (svga->multiplexing_rate == 0) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; } - break; - default: - break; - } - break; - case S3_ELSAWIN1K_86C928: - case S3_ELSAWIN2K_86C928: - switch (s3->width) { - case 1024: - switch (svga->hdisp) { - case 256: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 512: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; + } + } else if (svga->getclock == ics2494_getclock) { /*ICS2494 clock chip*/ + if (svga->clock_multiplier == 1) { + if (svga->multiplexing_rate == 2) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; } - break; - case 1280: /*Account for the 1280x1024 resolution*/ - switch (svga->hdisp) { - case 320: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 640: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; + svga->clock *= 2.0; + } else { + if (svga->multiplexing_rate == 2) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + svga->clock *= 4.0; } - break; - case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ - switch (svga->hdisp) { - case 320: - case 384: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 576: - case 640: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - if (s3->ramdac_type == BT48X) { - if (!svga->interlace) { - if (svga->dispend >= 1024) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } else { - if (svga->dispend >= 512) { - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - } - } - } - break; - } - break; - default: - break; + } } break; default: @@ -3936,72 +3879,8 @@ s3_recalctimings(svga_t *svga) } break; case S3_86C928PCI: - switch (s3->card_type) { - case S3_ELSAWIN1KPCI_86C928: - switch (s3->width) { - case 1024: - switch (svga->hdisp) { - case 256: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 512: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; - } - break; - case 1280: /*Account for the 1280x1024 resolution*/ - switch (svga->hdisp) { - case 320: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 640: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; - } - break; - case 2048: /*Account for the 1280x1024 resolution and the ELSA EEPROM resolutions*/ - switch (svga->hdisp) { - case 320: - case 384: - svga->hdisp <<= 2; - svga->dots_per_clock <<= 2; - break; - case 576: - case 640: - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - break; - default: - break; - } - break; - default: - break; - } - break; - - case S3_SPEA_MERCURY_LITE_PCI: - switch (s3->width) { - case 640: - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - break; - default: - break; - } - break; - - default: - break; - } + if (!svga->chain4) + svga->chain4 |= 0x08; break; case S3_VISION964: switch (s3->card_type) { @@ -4126,69 +4005,82 @@ s3_recalctimings(svga_t *svga) } break; case S3_86C928: - switch (s3->card_type) { - case S3_METHEUS_86C928: - if (!s3->color_16bit) { - s3_log("928 15bpp: ClockSel=%02x, width=%d, hdisp=%d, dotsperclock=%d.\n", clk_sel, s3->width, svga->hdisp, svga->dots_per_clock); - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; - } - switch (svga->hdisp) { /*This might be a driver issue*/ - case 800: - s3->width = 1024; - break; - case 1280: - s3->width = 2048; - break; - default: - break; - } - break; - case S3_ELSAWIN1K_86C928: - case S3_ELSAWIN2K_86C928: - switch (s3->width) { - case 2048: - if (s3->ramdac_type == SC1502X) { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } else { + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) { + if (svga->multiplexing_rate == 1) { + if (svga->true_color_bypass) { + if (svga->crtc[0x31] & 0x02) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + svga->clock *= 2.0; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + if (!svga->clock_multiplier) + svga->clock *= 2.0; + } + } + } else { + if (svga->multiplexing_rate == 1) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; + svga->clock *= 2.0; } - break; - default: - if (s3->ramdac_type == BT48X) - svga->clock /= 2.0; - else if (s3->ramdac_type == SC1502X) { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } - break; + } + } else if (svga->getclock == ics2494_getclock) { /*ICS2494 clock chip*/ + if (svga->multiplexing_rate == 1) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } + } + break; + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + } else { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } } break; - default: break; } break; case S3_86C928PCI: - switch (s3->card_type) { - case S3_ELSAWIN1KPCI_86C928: - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - break; - case S3_SPEA_MERCURY_LITE_PCI: - switch (s3->width) { - case 640: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + } else { svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - break; - default: - break; + } + } else if (svga->getclock == av9194_getclock) { /*AV9194 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + } else { + if (s3->width == 640) + svga->hdisp >>= 1; + } } break; - default: break; } @@ -4350,67 +4242,82 @@ s3_recalctimings(svga_t *svga) } break; case S3_86C928: - switch (s3->card_type) { - case S3_METHEUS_86C928: - s3_log("928 16bpp: ClockSel=%02x, width=%d, hdisp=%d, dotsperclock=%d.\n", clk_sel, s3->width, svga->hdisp, svga->dots_per_clock); - svga->hdisp <<= 1; - svga->dots_per_clock <<= 1; - svga->clock *= 2.0; - switch (svga->hdisp) { /*This might be a driver issue*/ - case 800: - s3->width = 1024; - break; - case 1280: - s3->width = 2048; - break; - default: - break; - } - break; - case S3_ELSAWIN1K_86C928: - case S3_ELSAWIN2K_86C928: - switch (s3->width) { - case 2048: - if (s3->ramdac_type == SC1502X) { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } else { + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) { + if (svga->multiplexing_rate == 1) { + if (svga->true_color_bypass) { + if (svga->crtc[0x31] & 0x02) { + svga->hdisp <<= 2; + svga->dots_per_clock <<= 2; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + svga->clock *= 2.0; + } else { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + if (!svga->clock_multiplier) + svga->clock *= 2.0; + } + } + } else { + if (svga->multiplexing_rate == 1) { svga->hdisp <<= 1; svga->dots_per_clock <<= 1; + svga->clock *= 2.0; } - break; - default: - if (s3->ramdac_type == BT48X) - svga->clock /= 2.0; - else if (s3->ramdac_type == SC1502X) { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - } - break; + } + } else if (svga->getclock == ics2494_getclock) { /*ICS2494 clock chip*/ + if (svga->multiplexing_rate == 1) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } + } + break; + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + } else { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } } break; - default: break; } break; case S3_86C928PCI: - switch (s3->card_type) { - case S3_ELSAWIN1KPCI_86C928: - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; - break; - case S3_SPEA_MERCURY_LITE_PCI: - switch (s3->width) { - case 640: + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + } else { svga->hdisp >>= 1; svga->dots_per_clock >>= 1; - break; - default: - break; + } + } else if (svga->getclock == av9194_getclock) { /*AV9194 clock chip*/ + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->clock *= 2.0; + } else { + if (s3->width == 640) + svga->hdisp >>= 1; + } } break; - default: break; } @@ -4561,8 +4468,22 @@ s3_recalctimings(svga_t *svga) break; } break; - case S3_86C928PCI: + case S3_86C928: /*Technically the 928 cards don't support 24bpp.*/ + if (!svga->chain4) + svga->chain4 |= 0x08; + break; + case S3_86C928PCI: /*Technically the 928 cards don't support 24bpp.*/ switch (s3->card_type) { + case S3_ELSAWIN1KPCI_86C928: + if (svga->dots_per_clock == 16) { + svga->dots_per_clock >>= 1; + svga->hdisp = (svga->hdisp << 1) / 3; + svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; + svga->clock /= (2.0 / 3.0); + if (svga->hdisp == 640) + s3->width = 640; + } + break; case S3_SPEA_MERCURY_LITE_PCI: svga->hdisp = (svga->hdisp << 1) / 3; svga->dots_per_clock = (svga->dots_per_clock << 1) / 3; @@ -4602,22 +4523,54 @@ s3_recalctimings(svga_t *svga) svga->render = svga_render_32bpp_highres; switch (s3->chip) { case S3_86C928: - switch (s3->card_type) { - case S3_ELSAWIN1K_86C928: - svga->hdisp >>= 2; - svga->dots_per_clock >>= 2; - svga->clock *= 2.0; + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case BT48X: /*BT485 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if ((svga->clock_multiplier == 1) || (s3->width >= 1024)) { + if (svga->true_color_bypass) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + svga->clock *= 2.0; + } + } + if (svga->hdisp == 800) + s3->width = 1024; + } + break; + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (svga->crtc[0x31] & 0x02) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + if (svga->hdisp == 640) + s3->width = 1024; + } else { + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + if (svga->hdisp == 800) + s3->width = 1024; + } + } break; default: break; } break; case S3_86C928PCI: - switch (s3->card_type) { - case S3_ELSAWIN1KPCI_86C928: - svga->hdisp >>= 2; - svga->dots_per_clock >>= 2; - svga->clock *= 2.0; + if (!svga->chain4) + svga->chain4 |= 0x08; + switch (s3->ramdac_type) { + case SC1502X: /*SC15025 RAMDAC*/ + if (svga->getclock == icd2061_getclock) { /*ICD2061 clock chip*/ + if (!(svga->crtc[0x31] & 0x02)) { + svga->hdisp >>= 2; + svga->dots_per_clock >>= 2; + if (s3->width >= 800) + svga->clock *= 2.0; + } + } break; default: break; @@ -10792,7 +10745,8 @@ s3_init(const device_t *info) /* DCS2824-0 = Diamond ICD2061A-compatible. */ svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; - icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); + icd2061_set_ref_clock(svga->ramdac, 14318184.0f); + svga_recalctimings(svga); } break; @@ -10890,7 +10844,8 @@ s3_init(const device_t *info) svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; s3->elsa_eeprom = 1; - icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + icd2061_set_ref_clock(svga->ramdac, 28322000.0f); + svga_recalctimings(svga); break; case S3_ELSAWIN2K_86C928: @@ -10906,7 +10861,8 @@ s3_init(const device_t *info) svga->clock_gen = device_add(&ics9161_device); svga->getclock = ics9161_getclock; s3->elsa_eeprom = 1; - icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + icd2061_set_ref_clock(svga->ramdac, 28322000.0f); + svga_recalctimings(svga); break; case S3_METHEUS_86C928: @@ -10936,7 +10892,8 @@ s3_init(const device_t *info) svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; s3->elsa_eeprom = 1; - icd2061_set_ref_clock(svga->ramdac, svga, 28322000.0f); + icd2061_set_ref_clock(svga->ramdac, 28322000.0f); + svga_recalctimings(svga); break; case S3_SPEA_MERCURY_LITE_PCI: @@ -10996,7 +10953,8 @@ s3_init(const device_t *info) s3->ramdac_type = BT48X; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; - icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); + icd2061_set_ref_clock(svga->ramdac, 14318184.0f); + svga_recalctimings(svga); break; } break; @@ -11075,7 +11033,8 @@ s3_init(const device_t *info) s3->ramdac_type = ATT498; svga->clock_gen = device_add(&icd2061_device); svga->getclock = icd2061_getclock; - icd2061_set_ref_clock(svga->ramdac, svga, 14318184.0f); + icd2061_set_ref_clock(svga->ramdac, 14318184.0f); + svga_recalctimings(svga); } else { svga->ramdac = device_add(&sdac_ramdac_device); s3->ramdac_type = S3_SDAC; From 0a22140c709736bd22826598790ec45c649cd04f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 15:56:00 +0000 Subject: [PATCH 116/138] Try for some fixes --- src/codegen_new/codegen.c | 15 +++------------ src/codegen_new/codegen_ir.c | 1 + src/codegen_new/codegen_ops_helpers.h | 1 - 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index 48d2afad9..bffa6b513 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -30,12 +30,6 @@ static struct { int TOP; } codegen_instructions[MAX_INSTRUCTION_COUNT]; -void -codegen_print_mmx(const char* str, uint32_t fetchdat) -{ - pclog("MMX results: %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX, %016llX (%s, fetchdat 0x%08X)\n", (unsigned long long)cpu_state.MM[0].q, (unsigned long long)cpu_state.MM[1].q, (unsigned long long)cpu_state.MM[2].q, (unsigned long long)cpu_state.MM[3].q, (unsigned long long)cpu_state.MM[4].q, (unsigned long long)cpu_state.MM[5].q, (unsigned long long)cpu_state.MM[6].q, (unsigned long long)cpu_state.MM[7].q, str, fetchdat); -} - int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) { @@ -746,12 +740,9 @@ codegen_skip: else uop_MOV_IMM(ir, IREG_pc, op_pc + pc_off); uop_MOV_IMM(ir, IREG_oldpc, old_pc); - if (op_32 != last_op_32) - uop_MOV_IMM(ir, IREG_op32, op_32); - if (op_ea_seg != last_op_ea_seg) - uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); - if (op_ssegs != last_op_ssegs) - uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); + uop_MOV_IMM(ir, IREG_op32, op_32); + uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); + uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); uop_CALL_INSTRUCTION_FUNC(ir, op, fetchdat); codegen_flags_changed = 0; codegen_mark_code_present(block, cs + cpu_state.pc, 8); diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index d14fa0f23..dfd136289 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -53,6 +53,7 @@ duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) new_uop->imm_data = uop->imm_data; new_uop->p = uop->p; new_uop->pc = uop->pc; + new_uop->is_a16 = uop->is_a16; if (uop->jump_dest_uop != -1) { new_uop->jump_dest_uop = uop->jump_dest_uop + offset; diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 0128e15ae..92b721099 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,7 +114,6 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - return 0; if (block->flags & CODEBLOCK_BYTE_MASK) return 0; From 7ac4b8de3a97b9dd7cdbbcf4bd7b613d5f5846f1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 17:39:22 +0000 Subject: [PATCH 117/138] Revert some changes --- src/codegen_new/codegen.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index bffa6b513..875dd72ca 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -740,9 +740,12 @@ codegen_skip: else uop_MOV_IMM(ir, IREG_pc, op_pc + pc_off); uop_MOV_IMM(ir, IREG_oldpc, old_pc); - uop_MOV_IMM(ir, IREG_op32, op_32); - uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); - uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); + if (op_32 != last_op_32) + uop_MOV_IMM(ir, IREG_op32, op_32); + if (op_ea_seg != last_op_ea_seg) + uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); + if (op_ssegs != last_op_ssegs) + uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); uop_CALL_INSTRUCTION_FUNC(ir, op, fetchdat); codegen_flags_changed = 0; codegen_mark_code_present(block, cs + cpu_state.pc, 8); From fed75595da92648752baf2af5bc70a74c75c8dc8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 19:09:06 +0000 Subject: [PATCH 118/138] Disable unrolling optimizations on ARM64 --- src/codegen_new/codegen_ops_helpers.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 92b721099..61711d1ed 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,6 +114,10 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { + /* TODO: Re-enable this again after fixing mysterious crashes on ARM64. */ +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 + return 0; +#endif if (block->flags & CODEBLOCK_BYTE_MASK) return 0; From cc7ca6c65226ae7dd07e6d009d34699107ca1e79 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Mon, 15 Sep 2025 19:13:51 +0000 Subject: [PATCH 119/138] Cleanups --- src/codegen_new/codegen_backend_arm64_uops.c | 4 ---- src/codegen_new/codegen_ops.c | 8 ++++++++ src/codegen_new/codegen_ops_helpers.h | 2 +- src/codegen_new/codegen_ops_mmx_loadstore.c | 2 -- src/codegen_new/codegen_ops_mmx_logic.c | 1 - 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index c4923387c..d06685cb2 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -1484,10 +1484,6 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); host_arm64_SQXTUN_V8B_8H(block, dest_reg, REG_V_TEMP); - //host_arm64_ADD_V4H(block, dest_reg, dest_reg, src_reg_b); - //host_arm64_SQXTUN_V8B_8H(block, REG_V_TEMP, src_reg_b); - //host_arm64_SQXTUN_V8B_8H(block, dest_reg, dest_reg); - //host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 039e0877a..68861ff52 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -97,7 +97,11 @@ RecompOpFn recomp_opcodes_0f[512] = { /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#endif /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -119,7 +123,11 @@ RecompOpFn recomp_opcodes_0f[512] = { /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +#endif // clang-format on }; diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 61711d1ed..05928bd2f 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,7 +114,7 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - /* TODO: Re-enable this again after fixing mysterious crashes on ARM64. */ + /* TODO: Re-enable this again after fixing mysterious crashes on ARM64 with MMX instructions used. */ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 return 0; #endif diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index e46af7e44..9d37228ec 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -16,8 +16,6 @@ #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str, uint32_t fetchdat); - uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index dec8d8c04..dd50b486e 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -16,7 +16,6 @@ #include "codegen_ops_mmx_logic.h" #include "codegen_ops_helpers.h" -extern void codegen_print_mmx(const char* str, uint32_t fetchdat); uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, UNUSED(uint8_t opcode), uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { From 4735423f8209ba75fbe78763e304d7cd04192114 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:24:28 +0800 Subject: [PATCH 120/138] machine.h: BIOS Selector for Micronics M7S-Hi added. --- src/include/86box/machine.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 4431590a6..101ed2934 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -992,6 +992,9 @@ extern int machine_at_cu430hx_init(const machine_t *); extern const device_t tc430hx_device; #endif extern int machine_at_tc430hx_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t m7shi_device; +#endif extern int machine_at_m7shi_init(const machine_t *); extern int machine_at_epc2102_init(const machine_t *); extern int machine_at_pcv90_init(const machine_t *); From af6b627fc783cedc7f19ce098ac791a5c2145437 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:38:08 +0800 Subject: [PATCH 121/138] m_at_socket7.c: Micronics M7S-Hi Configuration... --- src/machine/m_at_socket7.c | 50 ++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index b82f54905..ee276566a 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -368,17 +368,57 @@ machine_at_tc430hx_init(const machine_t *model) return ret; } +static const device_config_t m7shi_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "m7shi", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "PhoenixBIOS 4.0 Release 6.0 - Revision 05/20/97", .internal_name = "m7shi", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/m7shi/m7shi2n.rom", "" } }, + { .name = "PhoenixBIOS 4.0 Release 6.0 - Revision 01/21/98", .internal_name = "m7shi_4", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/m7shi/M7ns04.rom", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t m7shi_device = { + .name = "Micronics M7S-Hi", + .internal_name = "m7shi_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = m7shi_config +}; + int machine_at_m7shi_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/m7shi/m7shi2n.rom", - 0x000c0000, 262144, 0); - - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000c0000, 262144, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1); From 0c866af8f96e294ac6572ce9e5d617ce1723da91 Mon Sep 17 00:00:00 2001 From: Verloren50000 <110334428+Verloren50000@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:39:46 +0800 Subject: [PATCH 122/138] BIOS Selector for Micronics M7S-Hi ROM is complete. --- src/machine/machine_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 1740947bc..3d241401d 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -14134,7 +14134,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &m7shi_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, From 81e4d95fc79e7a2018b6f9054d950b8f134327a6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 16 Sep 2025 22:14:52 +0200 Subject: [PATCH 123/138] Config: Fix HDC migration to avoid "internal" devices on hard disk controllers above the first and also remove them from the config on save. --- src/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index d3bc0c2de..53d00a6bf 100644 --- a/src/config.c +++ b/src/config.c @@ -1034,7 +1034,7 @@ load_storage_controllers(void) if (!hdc_current[j]) { if (!legacy_cards[i]) { if (!p) { - hdc_current[j] = hdc_get_from_internal_name("internal"); + hdc_current[j] = hdc_get_from_internal_name((j == 0) ? "internal" : "none"); } else if (!strcmp(p, "xtide_plus")) { hdc_current[j] = hdc_get_from_internal_name("xtide"); sprintf(temp, "PC/XT XTIDE #%i", j + 1); @@ -3063,7 +3063,7 @@ save_storage_controllers(void) else def_hdc = "none"; - if (!strcmp(hdc_get_internal_name(hdc_current[c]), def_hdc)) + if (!strcmp(hdc_get_internal_name(hdc_current[c]), def_hdc) || ((c > 0) && (hdc_current[c] == 1))) ini_section_delete_var(cat, temp); else ini_section_set_string(cat, temp, From e29d76f94696aae44218aad140640ab8d1d9df87 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 17 Sep 2025 02:52:26 +0600 Subject: [PATCH 124/138] Force all processed screenshots to be opaque --- src/qt/qt_openglrenderer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index cecc8ea9c..6f2357cf0 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -1713,6 +1713,11 @@ OpenGLRenderer::render() glw.glFinish(); glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + for (uint32_t idx = 0; idx < (uint32_t)(width * height); idx++) + { + rgba[idx * 4] = 255; + } + QImage image(rgba, width, height, QImage::Format_RGBA8888); image.mirrored(false, true).save(path, "png"); monitors[r_monitor_index].mon_screenshots--; From d8380b07a9560dfdca7497b2e01ee422489d564c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miran=20Gr=C4=8Da?= Date: Tue, 16 Sep 2025 23:50:45 +0200 Subject: [PATCH 125/138] ET4000/W32* PCI: Revert BIOS read/write code to PCem's, fixes #6175. --- src/video/vid_et4000w32.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 3f661eabd..181c3a833 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2654,9 +2654,9 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) case 0x31: return 0x00; case 0x32: - return 0x00; + return et4000->pci_regs[0x32]; case 0x33: - return et4000->pci_regs[0x33] & 0xf0; + return et4000->pci_regs[0x33]; default: break; @@ -2695,20 +2695,13 @@ et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) break; case 0x30: - case 0x31: case 0x32: case 0x33: et4000->pci_regs[addr] = val; - et4000->pci_regs[0x30] = 1; - et4000->pci_regs[0x31] = 0; - et4000->pci_regs[0x32] = 0; - et4000->pci_regs[0x33] &= 0xf0; if (et4000->pci_regs[0x30] & 0x01) { - uint32_t biosaddr = (et4000->pci_regs[0x33] << 24); - if (!biosaddr) - biosaddr = 0xc0000; - et4000w32_log("ET4000 bios_rom enabled at %08x\n", biosaddr); - mem_mapping_set_addr(&et4000->bios_rom.mapping, biosaddr, 0x8000); + uint32_t addr = (et4000->pci_regs[0x32] << 16) | (et4000->pci_regs[0x33] << 24); + et4000w32_log("ET4000 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&et4000->bios_rom.mapping, addr, 0x8000); } else { et4000w32_log("ET4000 bios_rom disabled\n"); mem_mapping_disable(&et4000->bios_rom.mapping); From 1545a80fb7e78548ec63573815f0350363629de9 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 17 Sep 2025 04:32:00 +0600 Subject: [PATCH 126/138] Save processed screenshots without an alpha channel --- src/qt/qt_openglrenderer.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 6f2357cf0..ced74024b 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -1708,20 +1708,15 @@ OpenGLRenderer::render() plat_tempfile(fn, NULL, (char*)".png"); strcat(path, fn); - unsigned char *rgba = (unsigned char *) calloc(1, (size_t) width * height * 4); + unsigned char *rgb = (unsigned char *) calloc(1, (size_t) width * height * 3); glw.glFinish(); - glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, rgba); + glw.glReadPixels(window_rect.x, window_rect.y, width, height, GL_RGB, GL_UNSIGNED_BYTE, rgb); - for (uint32_t idx = 0; idx < (uint32_t)(width * height); idx++) - { - rgba[idx * 4] = 255; - } - - QImage image(rgba, width, height, QImage::Format_RGBA8888); + QImage image(rgb, width, height, QImage::Format_RGB888); image.mirrored(false, true).save(path, "png"); monitors[r_monitor_index].mon_screenshots--; - free(rgba); + free(rgb); } glw.glDisable(GL_FRAMEBUFFER_SRGB); From 5577efe301aa8babdc32602470b2b73b0c7bbc4d Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 17 Sep 2025 22:50:18 +0600 Subject: [PATCH 127/138] Revert "Merge pull request #6172 from Cacodemon345/armfixes-2" This reverts commit 5bfa69f3da072b4e6fdf8d0e9e937e5a084b8963, reversing changes made to a54e33bf041e3a0cb311d51e5d97e0d41320d246. --- src/codegen_new/codegen_backend_arm64_ops.c | 28 ++---------------- src/codegen_new/codegen_backend_arm64_ops.h | 3 -- src/codegen_new/codegen_backend_arm64_uops.c | 29 +++++++++---------- src/codegen_new/codegen_backend_x86-64_uops.c | 12 ++++---- src/codegen_new/codegen_ir.c | 1 - src/codegen_new/codegen_ir_defs.h | 4 +-- src/codegen_new/codegen_ops.c | 26 +++++++++++++---- src/codegen_new/codegen_ops_helpers.h | 4 --- src/codegen_new/codegen_reg.c | 2 +- 9 files changed, 45 insertions(+), 64 deletions(-) diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 9d5806edf..915cae93d 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -102,10 +102,6 @@ # define OPCODE_SUB_LSR (0x25a << 21) # define OPCODE_SUBX_LSL (0x658 << 21) -# define OPCODE_INS_B (0x6e010400) -# define OPCODE_INS_H (0x6e020400) -# define OPCODE_INS_S (0x6e040400) -# define OPCODE_INS_D (0x6e080400) # define OPCODE_ADD_V8B (0x0e208400) # define OPCODE_ADD_V4H (0x0e608400) # define OPCODE_ADD_V2S (0x0ea08400) @@ -184,7 +180,6 @@ # define OPCODE_SQSUB_V8B (0x0e202c00) # define OPCODE_SQSUB_V4H (0x0e602c00) # define OPCODE_SQXTN_V8B_8H (0x0e214800) -# define OPCODE_SQXTUN_V8B_8H (0x2e212800) # define OPCODE_SQXTN_V4H_4S (0x0e614800) # define OPCODE_SHL_VD (0x0f005400) # define OPCODE_SHL_VQ (0x4f005400) @@ -212,7 +207,6 @@ # define OPCODE_ZIP1_V8B (0x0e003800) # define OPCODE_ZIP1_V4H (0x0e403800) # define OPCODE_ZIP1_V2S (0x0e803800) -# define OPCODE_ZIP1_V2D (0x4ec03800) # define OPCODE_ZIP2_V8B (0x0e007800) # define OPCODE_ZIP2_V4H (0x0e407800) # define OPCODE_ZIP2_V2S (0x0e807800) @@ -231,11 +225,11 @@ # define IMM_LOGICAL(imm) ((imm) << 10) -# define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) +# define BIT_TBxZ(bit) ((((bit) &0x1f) << 19) | (((bit) &0x20) ? (1 << 31) : 0)) # define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) # define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) +# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) &0x1fffff) >> 2) << 5)) # define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) # define OFFSET12_B(offset) (offset << 10) @@ -722,12 +716,6 @@ host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } -void -host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index) -{ - codegen_addlong(block, OPCODE_INS_D | Rd(dst_reg) | Rn(src_reg) | ((dst_index & 1) << 20) | ((src_index & 1) << 14)); -} - void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { @@ -1237,13 +1225,6 @@ host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } - -void -host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_addlong(block, OPCODE_SQXTUN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); -} - void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { @@ -1494,11 +1475,6 @@ host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_re codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } void -host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) -{ - codegen_addlong(block, OPCODE_ZIP1_V2D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); -} -void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index 129c2b2a3..df751b4aa 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -72,7 +72,6 @@ void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_ void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element); -void host_arm64_INS_D(codeblock_t *block, int dst_reg, int src_reg, int dst_index, int src_index); void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data); void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift); @@ -185,7 +184,6 @@ void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int sr void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); -void host_arm64_SQXTUN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg); void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_reg, int shift); @@ -245,7 +243,6 @@ void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_reg, int shift void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); -void host_arm64_ZIP1_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index d06685cb2..2bb6281ff 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -801,8 +801,7 @@ codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 1); - host_arm64_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); + host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); return 0; } @@ -850,28 +849,28 @@ codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_MOVX_IMM(block, REG_ARG0, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_MOVX_IMM(block, REG_ARG1, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_MOVX_IMM(block, REG_ARG2, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); return 0; } static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_MOVX_IMM(block, REG_ARG3, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); return 0; } @@ -1449,9 +1448,9 @@ codegen_PACKSSWB(codeblock_t *block, uop_t *uop) 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_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); - host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); - host_arm64_SQXTN_V8B_8H(block, dest_reg, REG_V_TEMP); + host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1466,9 +1465,9 @@ codegen_PACKSSDW(codeblock_t *block, uop_t *uop) 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_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); - host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); - host_arm64_SQXTN_V4H_4S(block, dest_reg, REG_V_TEMP); + host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); @@ -1481,9 +1480,9 @@ codegen_PACKUSWB(codeblock_t *block, uop_t *uop) int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { - host_arm64_INS_D(block, REG_V_TEMP, dest_reg, 0, 0); - host_arm64_INS_D(block, REG_V_TEMP, src_reg_b, 1, 0); - host_arm64_SQXTUN_V8B_8H(block, dest_reg, REG_V_TEMP); + host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); } else fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 6b206d5b5..356c8bcde 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -220,9 +220,9 @@ static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); # else - host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); # endif host_x86_CALL(block, uop->p); host_x86_TEST32_REG(block, REG_EAX, REG_EAX); @@ -906,9 +906,9 @@ static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV64_REG_IMM(block, REG_RCX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); # else - host_x86_MOV64_REG_IMM(block, REG_RDI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); # endif return 0; } @@ -916,9 +916,9 @@ static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { # if _WIN64 - host_x86_MOV64_REG_IMM(block, REG_RDX, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); # else - host_x86_MOV64_REG_IMM(block, REG_RSI, uop->imm_data); + host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); # endif return 0; } diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index dfd136289..d14fa0f23 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -53,7 +53,6 @@ duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) new_uop->imm_data = uop->imm_data; new_uop->p = uop->p; new_uop->pc = uop->pc; - new_uop->is_a16 = uop->is_a16; if (uop->jump_dest_uop != -1) { new_uop->jump_dest_uop = uop->jump_dest_uop + offset; diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index bfc19373b..60f7badea 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -336,7 +336,7 @@ typedef struct uop_t { ir_reg_t src_reg_a; ir_reg_t src_reg_b; ir_reg_t src_reg_c; - uintptr_t imm_data; + uint32_t imm_data; void *p; ir_host_reg_t dest_reg_a_real; ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; @@ -601,7 +601,7 @@ uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_re } static inline void -uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uintptr_t imm) +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { uop_t *uop = uop_alloc(ir, uop_type); diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 68861ff52..bb7d1f3ee 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -86,8 +86,13 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, +#endif /*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -95,11 +100,13 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif @@ -112,8 +119,13 @@ RecompOpFn recomp_opcodes_0f[512] = { /*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#else /*60*/ ropPUNPCKLBW, ropPUNPCKLWD, ropPUNPCKLDQ, ropPACKSSWB, ropPCMPGTB, ropPCMPGTW, ropPCMPGTD, ropPACKUSWB, ropPUNPCKHBW, ropPUNPCKHWD, ropPUNPCKHDQ, ropPACKSSDW, NULL, NULL, ropMOVD_r_d, ropMOVQ_r_q, /*70*/ NULL, ropPSxxW_imm, ropPSxxD_imm, ropPSxxQ_imm, ropPCMPEQB, ropPCMPEQW, ropPCMPEQD, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVD_d_r, ropMOVQ_q_r, +#endif /*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, /*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -121,11 +133,13 @@ RecompOpFn recomp_opcodes_0f[512] = { /*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +#else /*d0*/ NULL, NULL, NULL, NULL, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -#else /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif // clang-format on diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 05928bd2f..92b721099 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -114,10 +114,6 @@ int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - /* TODO: Re-enable this again after fixing mysterious crashes on ARM64 with MMX instructions used. */ -#if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 - return 0; -#endif if (block->flags & CODEBLOCK_BYTE_MASK) return 0; diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index b678bd6ac..f91377df8 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -201,7 +201,7 @@ static const uint8_t native_requested_sizes[9][8] = [REG_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, [REG_FPU_ST_DOUBLE][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1, - [REG_POINTER][IREG_SIZE_Q >> IREG_SIZE_SHIFT] = 1 + [REG_POINTER][(sizeof(void *) == 4) ? (IREG_SIZE_L >> IREG_SIZE_SHIFT) : (IREG_SIZE_Q >> IREG_SIZE_SHIFT)] = 1 }; void From caaa1aad4539b14dc2ec57448ac264a94ed56b42 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 17 Sep 2025 21:55:56 +0200 Subject: [PATCH 128/138] Reintroduce -mstackrealign as it seems to reduce CPU usage. --- cmake/flags-gcc.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/flags-gcc.cmake b/cmake/flags-gcc.cmake index 90eb52cd1..fcb507907 100644 --- a/cmake/flags-gcc.cmake +++ b/cmake/flags-gcc.cmake @@ -14,8 +14,8 @@ # # Define our flags -string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") -string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing") +string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -mstackrealign -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") +string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -mstackrealign -Wall -fno-strict-aliasing") string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og") From 942a8e96b17fc08cfda4ca7bd42ed89005378675 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 18 Sep 2025 02:12:14 +0600 Subject: [PATCH 129/138] Restore earlier OPL4 identification method (part 1) --- src/sound/ymfm/ymfm_pcm.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sound/ymfm/ymfm_pcm.cpp b/src/sound/ymfm/ymfm_pcm.cpp index 34417490c..a2e17144e 100644 --- a/src/sound/ymfm/ymfm_pcm.cpp +++ b/src/sound/ymfm/ymfm_pcm.cpp @@ -46,6 +46,7 @@ namespace ymfm void pcm_registers::reset() { std::fill_n(&m_regdata[0], REGISTERS, 0); + m_regdata[0x02] = 0x20; m_regdata[0xf8] = 0x1b; } From da6e55146365982e034779740e618e0ead1088db Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 18 Sep 2025 02:17:20 +0600 Subject: [PATCH 130/138] Restore earlier OPL4 identification method (part 2) --- src/sound/ymfm/ymfm_opl.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sound/ymfm/ymfm_opl.cpp b/src/sound/ymfm/ymfm_opl.cpp index 8e8025fd9..b70102b65 100644 --- a/src/sound/ymfm/ymfm_opl.cpp +++ b/src/sound/ymfm/ymfm_opl.cpp @@ -1717,14 +1717,8 @@ uint8_t ymf278b::read_data_pcm() { // read from PCM if (bitfield(m_address, 9) != 0) - { - uint8_t result = m_pcm.read(m_address & 0xff); - if ((m_address & 0xff) == 0x02) - result |= 0x20; - - return result; - } - return 0; + return m_pcm.read(m_address & 0xff); + return 0; } From ac1f091a62d7816470a5da45bb0182864d3188ac Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Sep 2025 00:30:24 +0200 Subject: [PATCH 131/138] Remove the excess -mstackrealign and only run the Discord timer if Discord integration is enabled. --- cmake/flags-gcc.cmake | 4 ++-- src/qt/qt_main.cpp | 6 ++++-- src/qt/qt_mainwindow.cpp | 5 ++++- src/qt/qt_mainwindow.hpp | 2 ++ 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/cmake/flags-gcc.cmake b/cmake/flags-gcc.cmake index fcb507907..90eb52cd1 100644 --- a/cmake/flags-gcc.cmake +++ b/cmake/flags-gcc.cmake @@ -14,8 +14,8 @@ # # Define our flags -string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -mstackrealign -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") -string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -mstackrealign -Wall -fno-strict-aliasing") +string(APPEND CMAKE_C_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing -Werror=implicit-int -Werror=implicit-function-declaration -Werror=int-conversion -Werror=strict-prototypes -Werror=old-style-definition") +string(APPEND CMAKE_CXX_FLAGS_INIT " -fomit-frame-pointer -Wall -fno-strict-aliasing") string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -g0 -O3") string(APPEND CMAKE_C_FLAGS_DEBUG_INIT " -ggdb -Og") diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 664b495bd..2bc3eacbb 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -515,6 +515,8 @@ main_thread_fn() static std::thread *main_thread; +QTimer discordupdate; + #ifdef Q_OS_WINDOWS WindowsDarkModeFilter* vmm_dark_mode_filter = nullptr; #endif @@ -865,7 +867,6 @@ main(int argc, char *argv[]) onesec.start(1000); #ifdef DISCORD - QTimer discordupdate; if (discord_loaded) { QTimer::singleShot(1000, &app, [] { if (enable_discord) { @@ -877,7 +878,8 @@ main(int argc, char *argv[]) QObject::connect(&discordupdate, &QTimer::timeout, &app, [] { discord_run_callbacks(); }); - discordupdate.start(1000); + if (enable_discord) + discordupdate.start(1000); } #endif diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 4f616e61b..954547078 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -2344,8 +2344,11 @@ MainWindow::on_actionEnable_Discord_integration_triggered(bool checked) if (enable_discord) { discord_init(); discord_update_activity(dopause); - } else + discordupdate.start(1000); + } else { discord_close(); + discordupdate.stop(); + } #endif } diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 792685f42..f562c2ea9 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -15,6 +15,8 @@ #include "qt_vmmanager_protocol.hpp" +extern QTimer discordupdate; + class MediaMenu; class RendererStack; From 2ba7b4a7681891a71f1901f069f4b23662df4fdc Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Sep 2025 04:26:13 +0200 Subject: [PATCH 132/138] Changed version to 5.2. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- src/unix/assets/86Box.spec | 4 ++-- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 127f0e53c..57e3b178f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 6.0 + VERSION 5.2 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index 7772e71de..cfb4bd9d0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (6.0) UNRELEASED; urgency=medium +86box (5.2) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Sun, 14 Sep 2025 01:57:44 +0200 + -- Jasmine Iwanek Thu, 18 Sep 2025 04:25:57 +0200 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index e71497698..27805a9e4 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -15,7 +15,7 @@ %global romver 4.1 Name: 86Box -Version: 6.0 +Version: 5.2 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Sat Aug 31 Jasmine Iwanek 6.0-1 +* Sat Aug 31 Jasmine Iwanek 5.2-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index 629ae8a08..fd633d426 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -11,7 +11,7 @@ net.86box.86Box.desktop - + diff --git a/vcpkg.json b/vcpkg.json index 6a4f6376c..73f6d08f8 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "6.0", + "version-string": "5.2", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later", From 381a06a44ce3e1eedd46e340345944d6e7f448d0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Sep 2025 04:32:23 +0200 Subject: [PATCH 133/138] Qt Software Rendrer: Use a casted comparison instead of calling memcmp(). --- src/qt/qt_softwarerenderer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index a8c0229d3..49f683bc0 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -59,8 +59,7 @@ SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { /* TODO: should look into deleteLater() */ auto tval = this; - void *nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) + if ((void *) tval == nullptr) return; auto origSource = source; From 376dccf86d1d6b32294db059b7722396e39d2c68 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 Sep 2025 04:37:11 +0200 Subject: [PATCH 134/138] Qt Software renderer: Use a simple XOR instead of increase and modulo 2. --- src/qt/qt_softwarerenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 49f683bc0..bb6c7508b 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -64,7 +64,7 @@ SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) auto origSource = source; cur_image = buf_idx; - buf_usage[(buf_idx + 1) % 2].clear(); + buf_usage[buf_idx ^ 1].clear(); source.setRect(x, y, w, h); From a9861c04f23665c1f69806eb0298479fcdf1cfe8 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Thu, 18 Sep 2025 15:10:33 +0600 Subject: [PATCH 135/138] Actually fix OPL4 ID readbacks --- src/sound/ymfm/ymfm_opl.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sound/ymfm/ymfm_opl.cpp b/src/sound/ymfm/ymfm_opl.cpp index b70102b65..99cddd05e 100644 --- a/src/sound/ymfm/ymfm_opl.cpp +++ b/src/sound/ymfm/ymfm_opl.cpp @@ -1716,8 +1716,14 @@ uint8_t ymf278b::read_status() uint8_t ymf278b::read_data_pcm() { // read from PCM - if (bitfield(m_address, 9) != 0) - return m_pcm.read(m_address & 0xff); + if (bitfield(m_address, 9) != 0) { + auto ret = m_pcm.read(m_address & 0xff); + if (m_address == 0x202) { + ret &= ~0xe0; + ret |= 0x20; + } + return ret; + } return 0; } From f1bfe4883218d02f8452af1d22671052a7b08b52 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 19 Sep 2025 14:50:30 +0600 Subject: [PATCH 136/138] Software renderer no longer uses QRasterWindow --- src/qt/qt_softwarerenderer.cpp | 33 ++++++++++++++++++++++++++++++--- src/qt/qt_softwarerenderer.hpp | 12 ++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index bb6c7508b..45c929db9 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -21,6 +21,7 @@ #include "qt_softwarerenderer.hpp" #include #include +#include extern "C" { #include <86box/86box.h> @@ -31,7 +32,7 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent) #ifdef __HAIKU__ : QWidget(parent) #else - : QRasterWindow(parent->windowHandle()) + : QWindow(parent->windowHandle()), m_backingStore(new QBackingStore(this)) #endif { RendererCommon::parentWidget = parent; @@ -47,12 +48,30 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent) #endif } +#ifdef __HAIKU__ void SoftwareRenderer::paintEvent(QPaintEvent *event) { (void) event; onPaint(this); } +#endif + +void +SoftwareRenderer::render() +{ + if (!isExposed()) + return; + + QRect rect(0, 0, width(), height()); + m_backingStore->beginPaint(rect); + + QPaintDevice *device = m_backingStore->paintDevice(); + onPaint(device); + + m_backingStore->endPaint(); + m_backingStore->flush(rect); +} void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) @@ -70,7 +89,11 @@ SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) if (source != origSource) onResize(this->width(), this->height()); +#ifdef __HAIKU__ update(); +#else + render(); +#endif } void @@ -80,7 +103,8 @@ SoftwareRenderer::resizeEvent(QResizeEvent *event) #ifdef __HAIKU__ QWidget::resizeEvent(event); #else - QRasterWindow::resizeEvent(event); + QWindow::resizeEvent(event); + m_backingStore->resize(event->size()); #endif } @@ -92,7 +116,7 @@ SoftwareRenderer::event(QEvent *event) #ifdef __HAIKU__ return QWidget::event(event); #else - return QRasterWindow::event(event); + return QWindow::event(event); #endif return res; } @@ -112,6 +136,9 @@ SoftwareRenderer::onPaint(QPaintDevice *device) #endif painter.setCompositionMode(QPainter::CompositionMode_Plus); painter.drawImage(destination, *images[cur_image], source); +#ifndef __HAIKU__ + painter.end(); +#endif } std::vector> diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp index ec64f7000..f8bd91338 100644 --- a/src/qt/qt_softwarerenderer.hpp +++ b/src/qt/qt_softwarerenderer.hpp @@ -2,8 +2,10 @@ #define SOFTWARERENDERER_HPP #include -#include +#include #include +#include +#include #include #include #include "qt_renderercommon.hpp" @@ -12,14 +14,16 @@ class SoftwareRenderer : #ifdef __HAIKU__ public QWidget, #else - public QRasterWindow, + public QWindow, #endif public RendererCommon { Q_OBJECT public: explicit SoftwareRenderer(QWidget *parent = nullptr); +#ifdef __HAIKU__ void paintEvent(QPaintEvent *event) override; +#endif std::vector> getBuffers() override; @@ -33,6 +37,10 @@ protected: void onPaint(QPaintDevice *device); void resizeEvent(QResizeEvent *event) override; bool event(QEvent *event) override; + + void render(); + + QScopedPointer m_backingStore; }; #endif // SOFTWARERENDERER_HPP From a1c974c045c420f7badbc21fb23ce31a92deb379 Mon Sep 17 00:00:00 2001 From: MaxwellS04 Date: Fri, 19 Sep 2025 16:31:32 +0700 Subject: [PATCH 137/138] Machine Changes 1. Changed the names for two Chaintech machines (for example, 333AXB and 416SX) 2. Added the "AB" name to ABIT machines 3. Removed the space from PCChips and PCPartner names 4. BIOS name related corrections 5. Make few machines use their latest revisions as default BIOS option --- src/machine/m_at_386dx.c | 4 +- src/machine/m_at_386sx.c | 2 +- src/machine/m_at_slot1.c | 20 +++--- src/machine/m_at_socket3.c | 8 +-- src/machine/m_at_socket7.c | 8 +-- src/machine/m_at_socket8.c | 2 +- src/machine/machine_table.c | 126 ++++++++++++++++++------------------ 7 files changed, 85 insertions(+), 85 deletions(-) diff --git a/src/machine/m_at_386dx.c b/src/machine/m_at_386dx.c index 9cb7c5223..7fb045d58 100644 --- a/src/machine/m_at_386dx.c +++ b/src/machine/m_at_386dx.c @@ -68,9 +68,9 @@ static const device_config_t deskpro386_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "September 1986", .internal_name = "deskpro386", .bios_type = BIOS_NORMAL, + { .name = "September 1986", .internal_name = "deskpro386_09_1986", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/deskpro386/1986-09-04-HI.json.bin", "" } }, - { .name = "May 1988", .internal_name = "deskpro386_05_1988", .bios_type = BIOS_NORMAL, + { .name = "May 1988", .internal_name = "deskpro386", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/deskpro386/1988-05-10.json.bin", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_386sx.c b/src/machine/m_at_386sx.c index 7e57c5902..0dc9142db 100644 --- a/src/machine/m_at_386sx.c +++ b/src/machine/m_at_386sx.c @@ -254,7 +254,7 @@ static const device_config_t c325ax_config[] = { }; const device_t c325ax_device = { - .name = "Chaintech 325AX", + .name = "Chaintech 3xxAX/AXB", .internal_name = "325ax_device", .flags = 0, .local = 0, diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index b80082d99..4c25799f6 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -359,9 +359,9 @@ static const device_config_t bx6_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "1998/07/28 - BIOS EG", .internal_name = "bx6", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision EG", .internal_name = "bx6_eg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/bx6/BX6_EG.BIN", "" } }, - { .name = "2000/03/10 - BIOS QS", .internal_name = "bx6_qs", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision QS", .internal_name = "bx6", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/bx6/BX6_QS.bin", "" } }, { .files_no = 0 } }, @@ -371,7 +371,7 @@ static const device_config_t bx6_config[] = { }; const device_t bx6_device = { - .name = "ABIT BX6", + .name = "ABIT AB-BX6", .internal_name = "bx6_device", .flags = 0, .local = 0, @@ -570,14 +570,14 @@ static const device_config_t ms6119_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Award Modular BIOS v4.51PG - Version 3.30b1 (LG IBM Multinet i x7G)", .internal_name = "lgibmx7g", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/ms6119.331", "" } }, - { .name = "Award Modular BIOS v4.51PG - Version 2.12 (Viglen Vig69M)", .internal_name = "vig69m", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/vig69m.212", "" } }, - { .name = "Award Modular BIOS v4.51PG - Version 2.10", .internal_name = "ms6119", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/w6119ims.2a0", "" } }, - { .name = "AMIBIOS 071595 - Version 1.90 (Packard Bell Tacoma)", .internal_name = "tacoma", .bios_type = BIOS_NORMAL, + { .name = "AMIBIOS 6 (071595) - Revision 1.90 (Packard Bell Tacoma)", .internal_name = "tacoma", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/A19P2190.ROM", "" } }, + { .name = "Award Modular BIOS v4.51PG - Revision 2.10", .internal_name = "ms6119", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/w6119ims.2a0", "" } }, + { .name = "Award Modular BIOS v4.51PG - Revision 2.12 (Viglen Vig69M)", .internal_name = "vig69m", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/vig69m.212", "" } }, + { .name = "Award Modular BIOS v4.51PG - Revision 3.30b1 (LG IBM Multinet i x7G)", .internal_name = "lgibmx7g", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 262144, .files = { "roms/machines/ms6119/ms6119.331", "" } }, { .files_no = 0 } }, }, diff --git a/src/machine/m_at_socket3.c b/src/machine/m_at_socket3.c index 2d6ea9730..8d460186c 100644 --- a/src/machine/m_at_socket3.c +++ b/src/machine/m_at_socket3.c @@ -178,11 +178,11 @@ static const device_config_t j403tg_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Award Modular BIOS v4.50G", .internal_name = "403tg", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/403TG.BIN", "" } }, - { .name = "AMI WinBIOS (121593)", .internal_name = "403tg_d", .bios_type = BIOS_NORMAL, + { .name = "AMI WinBIOS (121593)", .internal_name = "403tg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/J403TGRevD.BIN", "" } }, - { .name = "MR BIOS V2.02", .internal_name = "403tg_d_mr", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50G", .internal_name = "403tg_award", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/403TG.BIN", "" } }, + { .name = "MR BIOS V2.02", .internal_name = "403tg_mr", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/MRBiosOPT895.bin", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index ee276566a..2b02c5bf1 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -151,7 +151,7 @@ static const device_config_t cu430hx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Intel AMIBIOS - Revision 1.00.03.DK08 (Toshiba Equium 5200D)", .internal_name = "equium5200", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.03.DK08 (Toshiba Equium 5xx0D)", .internal_name = "equium5200", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1003DK08.BIO", "roms/machines/cu430hx/1003DK08.BI1", "roms/machines/cu430hx/1003DK08.BI2", "roms/machines/cu430hx/1003DK08.BI3", "roms/machines/cu430hx/1003DK08.RCV", "" } }, @@ -270,7 +270,7 @@ static const device_config_t tc430hx_config[] = { .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/tc430hx/1007DH0_.BIO", "roms/machines/tc430hx/1007DH0_.BI1", "roms/machines/tc430hx/1007DH0_.BI2", "roms/machines/tc430hx/1007DH0_.BI3", "roms/machines/tc430hx/1007DH0_.RCV", "" } }, - { .name = "Intel AMIBIOS - Revision 1.00.08.DH08 (Toshiba Infinia 7201)", .internal_name = "infinia7200", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.08.DH08 (Toshiba Infinia 7xx1)", .internal_name = "infinia7200", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/tc430hx/1008DH08.BIO", "roms/machines/tc430hx/1008DH08.BI1", "roms/machines/tc430hx/1008DH08.BI2", "roms/machines/tc430hx/1008DH08.BI3", "roms/machines/tc430hx/1008DH08.RCV", "" } }, @@ -1806,9 +1806,9 @@ static const device_config_t m5ata_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Award Modular BIOS v4.51PG - Revision 12/23/97", .internal_name = "m5ata", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 12/23/97", .internal_name = "m5ata_1223", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/m5ata/ATA1223.BIN", "" } }, - { .name = "Award Modular BIOS v4.51PG - Revision 05/27/98", .internal_name = "m5ata_0527b", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 05/27/98", .internal_name = "m5ata", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/m5ata/ATA0527B.BIN", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index 3d5f4787e..11262ef4a 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -111,7 +111,7 @@ static const device_config_t ficpo6000_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "405F03C", + .default_string = "405F05C", .default_int = 0, .file_filter = "", .spinner = { 0 }, /*W1*/ diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 3d241401d..47fe4823b 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -4075,7 +4075,7 @@ const machine_t machines[] = { .ram = { .min = 512, .max = 1024, - .step = 512 + .step = 128 }, .nvrmask = 63, .jumpered_ecp_dma = 0, @@ -5290,7 +5290,7 @@ const machine_t machines[] = { }, /* Has a JetKey KBC without version, which is a clone of AMI '8'. */ { - .name = "[ALi M1217] Chaintech 325AX", + .name = "[ALi M1217] Chaintech 3xxAX/AXB", .internal_name = "325ax", .type = MACHINE_TYPE_386SX, .chipset = MACHINE_CHIPSET_ALI_M1217, @@ -7385,7 +7385,7 @@ const machine_t machines[] = { /* Has AMIKey H KBC firmware, per the screenshot in "How computers & MS-DOS work". Also seen with an AMI 'F'. */ { - .name = "[SiS 401] Chaintech 433SC", + .name = "[SiS 401] Chaintech 4xxSX/SC", .internal_name = "sis401", .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_SIS_401, @@ -7429,7 +7429,7 @@ const machine_t machines[] = { }, /* Seen with both AMIKey F and AMIKey-2 H KBC firmwares. */ { - .name = "[SiS 460] ABIT AV4", + .name = "[SiS 460] ABIT AB-AV4", .internal_name = "av4", .type = MACHINE_TYPE_486, .chipset = MACHINE_CHIPSET_SIS_460, @@ -10682,7 +10682,7 @@ const machine_t machines[] = { /* This has the UMC 88xx on-chip KBC. All the copies of the BIOS string I can find, end in in -H, so the UMC on-chip KBC likely emulates the AMI 'H' KBC firmware. */ { - .name = "[UMC 8881] PC Chips M919", + .name = "[UMC 8881] PCChips M919", .internal_name = "m919", .type = MACHINE_TYPE_486_S3_PCI, .chipset = MACHINE_CHIPSET_UMC_UM8881, @@ -13198,7 +13198,7 @@ const machine_t machines[] = { }, /* Has a VIA VT82C42N KBC. */ { - .name = "[i430FX] PC Partner MB500N", + .name = "[i430FX] PCPartner MB500N", .internal_name = "mb500n", .type = MACHINE_TYPE_SOCKET7_3V, .chipset = MACHINE_CHIPSET_INTEL_430FX, @@ -13828,7 +13828,7 @@ const machine_t machines[] = { }, /* Has the ALi M1543 southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN IV+] PC Chips M560", + .name = "[ALi ALADDiN IV+] PCChips M560", .internal_name = "m560", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_IV_PLUS, @@ -14913,7 +14913,7 @@ const machine_t machines[] = { /* This has the AMIKey 'H' firmware, possibly AMIKey-2. Photos show it with a BestKey, so it likely clones the behavior of AMIKey 'H'. */ { - .name = "[i430VX] PC Partner MB520N", + .name = "[i430VX] PCPartner MB520N", .internal_name = "mb520n", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430VX, @@ -15377,7 +15377,7 @@ const machine_t machines[] = { /* The BIOS sends KBC command BB and expects it to output a byte, which is AMI KBC behavior. A picture shows a VIA VT82C42N KBC though, so it could be a case of that KBC with AMI firmware. */ { - .name = "[i430TX] PC Partner MB540N", + .name = "[i430TX] PCPartner MB540N", .internal_name = "mb540n", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_INTEL_430TX, @@ -15918,7 +15918,7 @@ const machine_t machines[] = { /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA VP3] PC Partner VIA809DS", + .name = "[VIA VP3] PCPartner VIA809DS", .internal_name = "via809ds", .type = MACHINE_TYPE_SOCKET7, .chipset = MACHINE_CHIPSET_VIA_APOLLO_VP3, @@ -16007,51 +16007,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge - with on-chip KBC. */ - { - .name = "[ALi ALADDiN V] PC Chips M579", - .internal_name = "m579", - .type = MACHINE_TYPE_SOCKETS7, - .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, - .init = machine_at_m579_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 66666667, - .max_bus = 100000000, - .min_voltage = 2000, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 5.5 - }, - .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ - .ram = { - .min = 8192, - .max = 1572864, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = NULL, - .kbc_params = 0x00000000, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = NULL, - .snd_device = NULL, - .net_device = NULL - }, /* M1534c kbc */ { .name = "[ALi ALADDiN V] Gateway Lucas", @@ -16184,6 +16139,51 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Is the exact same as the Matsonic MS6260S. Has the ALi M1543C southbridge + with on-chip KBC. */ + { + .name = "[ALi ALADDiN V] PCChips M579", + .internal_name = "m579", + .type = MACHINE_TYPE_SOCKETS7, + .chipset = MACHINE_CHIPSET_ALI_ALADDIN_V, + .init = machine_at_m579_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 66666667, + .max_bus = 100000000, + .min_voltage = 2000, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 5.5 + }, + .bus_flags = MACHINE_PS2_AGP | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, /* Machine has internal sound: C-Media CMI8330 */ + .ram = { + .min = 8192, + .max = 1572864, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* SiS 5591 */ /* Has the SiS 5591 chipset with on-chip KBC. */ @@ -16954,7 +16954,7 @@ const machine_t machines[] = { }, /* Has a VIA VT82C42N KBC. */ { - .name = "[i440FX] PC Partner MB600N", + .name = "[i440FX] PCPartner MB600N", .internal_name = "mb600n", .type = MACHINE_TYPE_SOCKET8, .chipset = MACHINE_CHIPSET_INTEL_440FX, @@ -17001,7 +17001,7 @@ const machine_t machines[] = { /* ALi ALADDiN-PRO II */ /* Has the ALi M1543C southbridge with on-chip KBC. */ { - .name = "[ALi ALADDiN-PRO II] PC Chips M729", + .name = "[ALi ALADDiN-PRO II] PCChips M729", .internal_name = "m729", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_ALI_ALADDIN_PRO_II, @@ -17183,7 +17183,7 @@ const machine_t machines[] = { /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[i440LX] ABIT LX6", + .name = "[i440LX] ABIT AB-LX6", .internal_name = "lx6", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440LX, @@ -17412,7 +17412,7 @@ const machine_t machines[] = { /* Has a Winbond W83977EF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[i440BX] ABIT BF6", + .name = "[i440BX] ABIT AB-BF6", .internal_name = "bf6", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, @@ -17457,7 +17457,7 @@ const machine_t machines[] = { /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[i440BX] ABIT BX6", + .name = "[i440BX] ABIT AB-BX6", .internal_name = "bx6", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_INTEL_440BX, @@ -17998,7 +17998,7 @@ const machine_t machines[] = { }, /* Has the SiS (5)600 chipset with on-chip KBC. */ { - .name = "[SiS 5600] PC Chips M747", + .name = "[SiS 5600] PCChips M747", .internal_name = "m747", .type = MACHINE_TYPE_SLOT1, .chipset = MACHINE_CHIPSET_SIS_5600, @@ -18879,7 +18879,7 @@ const machine_t machines[] = { /* Has an ITE IT8671F Super I/O chip with on-chip KBC with AMIKey-2 KBC firmware. */ { - .name = "[SMSC VictoryBX-66] PC Chips M773", + .name = "[SMSC VictoryBX-66] PCChips M773", .internal_name = "m773", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_SMSC_VICTORYBX_66, @@ -18926,7 +18926,7 @@ const machine_t machines[] = { /* Has the VIA VT82C586B southbridge with on-chip KBC identical to the VIA VT82C42N. */ { - .name = "[VIA Apollo Pro] PC Partner APAS3", + .name = "[VIA Apollo Pro] PCPartner APAS3", .internal_name = "apas3", .type = MACHINE_TYPE_SOCKET370, .chipset = MACHINE_CHIPSET_VIA_APOLLO_PRO, From cdd72a18b6a635ac92024c97f88871ef2c8745d1 Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 19 Sep 2025 15:46:36 +0600 Subject: [PATCH 138/138] Fix resize glitches while paused --- src/qt/qt_openglrenderer.cpp | 3 +++ src/qt/qt_softwarerenderer.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index ced74024b..962fa4d30 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -1223,6 +1223,9 @@ OpenGLRenderer::resizeEvent(QResizeEvent *event) destination.y(), destination.width(), destination.height()); + + if (video_framerate == -1) + render(); } void diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 45c929db9..8dee1dbe3 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -105,6 +105,7 @@ SoftwareRenderer::resizeEvent(QResizeEvent *event) #else QWindow::resizeEvent(event); m_backingStore->resize(event->size()); + render(); #endif }