From 84d96271dee2de8c83284181819d34fb64961c6b Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 Sep 2025 22:27:39 +0200 Subject: [PATCH 01/61] 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 02/61] 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 03/61] 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 04/61] (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 05/61] 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 06/61] 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 07/61] 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 08/61] 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 09/61] (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 10/61] (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 11/61] 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 12/61] (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 13/61] 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 14/61] 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 15/61] 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 16/61] 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 17/61] 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 18/61] 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 19/61] 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 20/61] 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 21/61] 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 22/61] 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 23/61] 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 24/61] 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 25/61] 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 26/61] 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 27/61] 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 28/61] 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 29/61] 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 30/61] 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 31/61] 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 32/61] 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 33/61] 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 34/61] 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 35/61] 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 36/61] 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 37/61] 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 38/61] 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 39/61] 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 40/61] 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 41/61] 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 42/61] 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 43/61] 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 44/61] 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 45/61] 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 46/61] 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 47/61] 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 48/61] 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 49/61] 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 50/61] 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 51/61] 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 52/61] 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 53/61] 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 54/61] 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 55/61] 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 56/61] 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 57/61] 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 58/61] 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 59/61] 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 60/61] 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 61/61] 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