From 3fe4f75108313b2fecad4bf24ab271f4b692a43d Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 19 Nov 2022 08:49:04 -0500 Subject: [PATCH 1/6] A bit more clang-format --- src/86box.c | 2 +- src/cdrom/cdrom_image_backend.c | 2 +- src/cdrom/cdrom_image_viso.c | 4 +- src/chipset/opti5x7.c | 2 +- src/chipset/opti822.c | 109 +- src/device/hwm_gl518sm.c | 4 +- src/device/hwm_lm78.c | 18 +- src/device/hwm_vt82c686.c | 4 +- src/device/isamem.c | 2 +- src/device/isartc.c | 2 +- src/device/keyboard_xt.c | 19 +- src/device/mouse_bus.c | 2 +- src/device/mouse_ps2.c | 26 +- src/device/mouse_serial.c | 2 +- src/device/serial.c | 2 +- src/disk/hdc_ide.c | 12 +- src/disk/hdc_st506_xt.c | 30 +- src/disk/hdd.c | 25 +- src/disk/hdd_table.c | 2 +- src/floppy/fdc.c | 32 +- src/floppy/fdc_magitronic.c | 2 +- src/floppy/fdc_pii15xb.c | 2 +- src/floppy/fdd.c | 2 +- src/floppy/fdd_img.c | 1312 ++++++++++---------- src/floppy/fdd_td0.c | 1258 +++++++++---------- src/game/gameport.c | 4 +- src/game/joystick_ch_flightstick_pro.c | 4 +- src/game/joystick_standard.c | 40 +- src/game/joystick_sw_pad.c | 6 +- src/game/joystick_tm_fcs.c | 6 +- src/include/86box/bswap.h | 172 +-- src/include/86box/fdc.h | 24 +- src/include/86box/fdd.h | 8 +- src/include/86box/hdc.h | 26 +- src/include/86box/hdd.h | 12 +- src/include/86box/i8080.h | 48 +- src/include/86box/language.h | 124 +- src/include/86box/machine.h | 5 +- src/include/86box/pci.h | 48 +- src/include/86box/plat.h | 2 +- src/include/86box/plat_dir.h | 37 +- src/include/86box/resource.h | 10 +- src/include/86box/vid_cga.h | 4 +- src/include/86box/vid_cga_comp.h | 2 +- src/include/86box/vid_voodoo_codegen_x86.h | 14 +- src/include/86box/vid_voodoo_common.h | 6 +- src/include/86box/vid_voodoo_dither.h | 2 +- src/include/fdi2raw.h | 24 +- src/include/tinyglib.h | 280 +++-- src/lpt.c | 2 +- src/machine/m_amstrad.c | 10 +- src/machine/m_at_compaq.c | 2 +- src/machine/m_xt.c | 29 +- src/machine/m_xt_olivetti.c | 132 +- src/machine/m_xt_t1000_vid.c | 2 +- src/machine/m_xt_xi8088.c | 2 +- src/machine/machine_table.c | 52 +- src/mem/mem.c | 28 +- src/network/net_pcnet.c | 50 +- src/network/net_slirp.c | 2 +- src/network/network.c | 4 +- src/network/pcap_if.c | 2 +- src/network/slirp/tinyglib.c | 97 +- src/pci.c | 16 +- src/printer/png.c | 4 +- src/printer/prt_ps.c | 2 +- src/qt/cocoa_mouse.hpp | 7 +- src/qt/evdev_mouse.cpp | 88 +- src/qt/macos_event_filter.mm | 100 +- src/qt/qt.c | 65 +- src/qt/qt_cdrom.c | 8 +- src/qt/qt_d3d9renderer.cpp | 103 +- src/qt/qt_d3d9renderer.hpp | 31 +- src/qt/qt_deviceconfig.cpp | 368 +++--- src/qt/qt_deviceconfig.hpp | 8 +- src/qt/qt_filefield.cpp | 16 +- src/qt/qt_filefield.hpp | 17 +- src/qt/qt_harddiskdialog.cpp | 431 ++++--- src/qt/qt_harddiskdialog.hpp | 18 +- src/qt/qt_harddrive_common.cpp | 100 +- src/qt/qt_harddrive_common.hpp | 12 +- src/qt/qt_hardwarerenderer.cpp | 200 +-- src/qt/qt_hardwarerenderer.hpp | 36 +- src/qt/qt_joystickconfiguration.cpp | 59 +- src/qt/qt_joystickconfiguration.hpp | 9 +- src/qt/qt_machinestatus.cpp | 470 +++---- src/qt/qt_machinestatus.hpp | 91 +- src/qt/qt_main.cpp | 96 +- src/qt/qt_mainwindow.cpp | 1175 ++++++++++-------- src/qt/qt_mainwindow.hpp | 55 +- src/qt/qt_mcadevicelist.cpp | 22 +- src/qt/qt_mcadevicelist.hpp | 3 +- src/qt/qt_mediahistorymanager.cpp | 132 +- src/qt/qt_mediahistorymanager.hpp | 181 ++- src/qt/qt_mediamenu.cpp | 445 ++++--- src/qt/qt_mediamenu.hpp | 38 +- src/qt/qt_midi.cpp | 64 +- src/qt/qt_models_common.cpp | 3 +- src/qt/qt_models_common.hpp | 5 +- src/qt/qt_newfloppydialog.cpp | 417 ++++--- src/qt/qt_newfloppydialog.hpp | 13 +- src/qt/qt_openglrenderer.cpp | 9 +- src/qt/qt_openglrenderer.hpp | 2 +- src/qt/qt_platform.cpp | 297 ++--- src/qt/qt_progsettings.cpp | 109 +- src/qt/qt_progsettings.hpp | 45 +- src/qt/qt_renderercommon.cpp | 100 +- src/qt/qt_renderercommon.hpp | 12 +- src/qt/qt_rendererstack.cpp | 134 +- src/qt/qt_rendererstack.hpp | 14 +- src/qt/qt_sdl.c | 646 +++++----- src/qt/qt_sdl.h | 24 +- src/qt/qt_settings.cpp | 76 +- src/qt/qt_settings.hpp | 35 +- src/qt/qt_settings_bus_tracking.cpp | 76 +- src/qt/qt_settings_bus_tracking.hpp | 37 +- src/qt/qt_settingsdisplay.cpp | 103 +- src/qt/qt_settingsdisplay.hpp | 5 +- src/qt/qt_settingsfloppycdrom.cpp | 134 +- src/qt/qt_settingsfloppycdrom.hpp | 3 +- src/qt/qt_settingsharddisks.cpp | 163 +-- src/qt/qt_settingsharddisks.hpp | 7 +- src/qt/qt_settingsinput.cpp | 97 +- src/qt/qt_settingsinput.hpp | 5 +- src/qt/qt_settingsmachine.cpp | 134 +- src/qt/qt_settingsmachine.hpp | 11 +- src/qt/qt_settingsnetwork.cpp | 95 +- src/qt/qt_settingsnetwork.hpp | 5 +- src/qt/qt_settingsotherperipherals.cpp | 83 +- src/qt/qt_settingsotherperipherals.hpp | 5 +- src/qt/qt_settingsotherremovable.cpp | 149 ++- src/qt/qt_settingsotherremovable.hpp | 3 +- src/qt/qt_settingsports.cpp | 48 +- src/qt/qt_settingsports.hpp | 3 +- src/qt/qt_settingssound.cpp | 146 ++- src/qt/qt_settingssound.hpp | 5 +- src/qt/qt_settingsstoragecontrollers.cpp | 130 +- src/qt/qt_settingsstoragecontrollers.hpp | 5 +- src/qt/qt_softwarerenderer.cpp | 36 +- src/qt/qt_softwarerenderer.hpp | 21 +- src/qt/qt_soundgain.cpp | 16 +- src/qt/qt_soundgain.hpp | 5 +- src/qt/qt_specifydimensions.cpp | 39 +- src/qt/qt_specifydimensions.h | 3 +- src/qt/qt_styleoverride.cpp | 18 +- src/qt/qt_styleoverride.hpp | 13 +- src/qt/qt_ui.cpp | 225 ++-- src/qt/qt_unixmanagerfilter.cpp | 51 +- src/qt/qt_unixmanagerfilter.hpp | 7 +- src/qt/qt_util.cpp | 45 +- src/qt/qt_util.hpp | 11 +- src/qt/qt_vulkanrenderer.cpp | 562 ++++----- src/qt/qt_vulkanrenderer.hpp | 59 +- src/qt/qt_vulkanwindowrenderer.cpp | 61 +- src/qt/qt_vulkanwindowrenderer.hpp | 21 +- src/qt/qt_winmanagerfilter.cpp | 19 +- src/qt/qt_winmanagerfilter.hpp | 7 +- src/qt/qt_winrawinputfilter.cpp | 228 ++-- src/qt/qt_winrawinputfilter.hpp | 27 +- src/qt/sdl_joystick.cpp | 118 +- src/qt/win_dynld.c | 44 +- src/qt/win_joystick_rawinput.c | 789 ++++++------ src/qt/wl_mouse.cpp | 73 +- src/qt/wl_mouse.hpp | 2 +- src/qt/xinput2_mouse.cpp | 141 ++- src/scsi/scsi.c | 4 +- src/scsi/scsi_cdrom.c | 236 ++-- src/scsi/scsi_ncr53c8xx.c | 6 +- src/scsi/scsi_pcscsi.c | 5 +- src/scsi/scsi_spock.c | 2 +- src/sound/midi_fluidsynth.c | 2 +- src/sound/midi_mt32.c | 2 +- src/sound/midi_rtmidi.cpp | 2 +- src/sound/snd_ac97_codec.c | 2 +- src/sound/snd_adlibgold.c | 2 +- src/sound/snd_audiopci.c | 2 +- src/sound/snd_azt2316a.c | 2 +- src/sound/snd_cmi8x38.c | 2 +- src/sound/snd_cms.c | 2 +- src/sound/snd_cs423x.c | 2 +- src/sound/snd_emu8k.c | 8 +- src/sound/snd_mpu401.c | 2 +- src/sound/snd_opl_nuked.c | 2 +- src/sound/snd_opl_ymfm.cpp | 8 +- src/sound/snd_pssj.c | 2 +- src/sound/snd_sn76489.c | 2 +- src/sound/snd_wss.c | 2 +- src/unix/macOSXGlue.m | 55 +- src/unix/unix.c | 2 +- src/upi42.c | 2 +- src/video/vid_ati_mach64.c | 2 +- src/video/vid_cga.c | 2 +- src/video/vid_colorplus.c | 2 +- src/video/vid_ega.c | 2 +- src/video/vid_et4000.c | 2 +- src/video/vid_et4000w32.c | 2 +- src/video/vid_hercules.c | 2 +- src/video/vid_herculesplus.c | 2 +- src/video/vid_ht216.c | 10 +- src/video/vid_mda.c | 2 +- src/video/vid_mga.c | 2 +- src/video/vid_nga.c | 2 +- src/video/vid_ogc.c | 2 +- src/video/vid_paradise.c | 2 +- src/video/vid_pgc.c | 6 +- src/video/vid_rtg310x.c | 2 +- src/video/vid_s3.c | 202 +-- src/video/vid_s3_virge.c | 2 +- src/video/vid_sigma.c | 2 +- src/video/vid_svga.c | 2 +- src/video/vid_table.c | 4 +- src/video/vid_tgui9440.c | 42 +- src/video/vid_tvga.c | 6 +- src/video/vid_voodoo.c | 2 +- src/video/vid_voodoo_banshee.c | 32 +- src/video/vid_voodoo_banshee_blitter.c | 30 +- src/video/vid_voodoo_reg.c | 4 +- src/video/vid_xga.c | 2 +- src/video/video.c | 5 +- src/win/win.c | 11 +- src/win/win_dynld.c | 22 +- src/win/win_settings.c | 20 +- src/win/win_ui.c | 10 +- 223 files changed, 8047 insertions(+), 7456 deletions(-) diff --git a/src/86box.c b/src/86box.c index 62520be88..235a1fd5d 100644 --- a/src/86box.c +++ b/src/86box.c @@ -769,7 +769,7 @@ usage: for (i = 0; i < FDD_NUM; i++) { if (fn[i] != NULL) { - if (strlen(fn[i]) <= 511) + if (strlen(fn[i]) <= 511) strncpy(floppyfns[i], fn[i], 511); free(fn[i]); fn[i] = NULL; diff --git a/src/cdrom/cdrom_image_backend.c b/src/cdrom/cdrom_image_backend.c index 8b28b6d37..d3f48578d 100644 --- a/src/cdrom/cdrom_image_backend.c +++ b/src/cdrom/cdrom_image_backend.c @@ -135,7 +135,7 @@ static track_file_t * bin_init(const char *filename, int *error) { track_file_t *tf = (track_file_t *) malloc(sizeof(track_file_t)); - struct stat stats; + struct stat stats; if (tf == NULL) { *error = 1; diff --git a/src/cdrom/cdrom_image_viso.c b/src/cdrom/cdrom_image_viso.c index 263e3c5f3..f420bf2fb 100644 --- a/src/cdrom/cdrom_image_viso.c +++ b/src/cdrom/cdrom_image_viso.c @@ -15,10 +15,10 @@ * Copyright 2022 RichardG. */ #ifndef _LARGEFILE_SOURCE -#define _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE #endif #ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE +# define _LARGEFILE64_SOURCE #endif #define __STDC_FORMAT_MACROS #include diff --git a/src/chipset/opti5x7.c b/src/chipset/opti5x7.c index 232d3426c..fdcb4fc3e 100644 --- a/src/chipset/opti5x7.c +++ b/src/chipset/opti5x7.c @@ -35,7 +35,7 @@ typedef struct { uint8_t idx, is_pci, - regs[16]; + regs[16]; } opti5x7_t; #ifdef ENABLE_OPTI5X7_LOG diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 2bdc62d66..7db233935 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -42,8 +42,8 @@ typedef struct { - uint8_t irq_convert, - pci_regs[256]; + uint8_t irq_convert, + pci_regs[256]; } opti822_t; // #define ENABLE_OPTI822_LOG 1 @@ -56,13 +56,13 @@ opti822_log(const char *fmt, ...) va_list ap; if (opti822_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define opti822_log(fmt, ...) +# define opti822_log(fmt, ...) #endif /* NOTE: We currently cheat and pass all PCI shadow RAM accesses to ISA as well. @@ -71,13 +71,13 @@ opti822_log(const char *fmt, ...) static void opti822_recalc(opti822_t *dev) { - int i, reg, bit_r, bit_w; - int state; + int i, reg, bit_r, bit_w; + int state; uint32_t base; for (i = 0; i < 12; i++) { - base = 0x000c0000 + (i << 14); - reg = 0x44 + ((i >> 2) ^ 3); + base = 0x000c0000 + (i << 14); + reg = 0x44 + ((i >> 2) ^ 3); bit_w = (i & 3); bit_r = bit_w + 4; bit_w = 1 << bit_w; @@ -99,19 +99,19 @@ static void opti822_update_irqs(opti822_t *dev, int set) { uint8_t val; - int i, reg; - int shift, irq; - int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; - pic_t *temp_pic; + int i, reg; + int shift, irq; + int irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + pic_t *temp_pic; // dev->irq_convert = (dev->pci_regs[0x53] & 0x08); dev->irq_convert = 1; for (i = 0; i < 16; i++) { - reg = 0x88 + (i >> 1); + reg = 0x88 + (i >> 1); shift = (i & 1) << 2; - val = (dev->pci_regs[reg] >> shift) & 0x0f; - irq = irq_map[val & 0x07]; + val = (dev->pci_regs[reg] >> shift) & 0x0f; + irq = irq_map[val & 0x07]; if (irq == -1) continue; temp_pic = (irq >= 8) ? &pic2 : &pic; @@ -127,8 +127,8 @@ static void opti822_pci_write(int func, int addr, uint8_t val, void *priv) { opti822_t *dev = (opti822_t *) priv; - int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; - int pin, slot; + int irq, irq_map[8] = { -1, 5, 9, 10, 11, 12, 14, 15 }; + int pin, slot; opti822_log("opti822_write(%02X, %02X, %02X)\n", func, addr, val); @@ -144,7 +144,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) /* Status Register */ case 0x06: if (!(dev->pci_regs[0x52] & 0x04)) - dev->pci_regs[addr] = (val & 0x80); + dev->pci_regs[addr] = (val & 0x80); break; case 0x07: dev->pci_regs[addr] &= ~(val & 0xf9); @@ -293,33 +293,33 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) dev->pci_regs[addr] = val; break; - case 0x88 ... 0x8f: - dev->pci_regs[addr] = val; - opti822_update_irqs(dev, 0); - irq = irq_map[val & 0x07]; - pin = 4 - ((addr & 0x01) << 1); - slot = ((addr & 0x06) >> 1); - if (irq >= 0) { - opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); - pci_set_irq_routing(pin + (slot << 2), irq); - pci_set_irq_level(pin + (slot << 2), !!(val & 0x07)); - } else { - opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); - pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); - } - irq = irq_map[(val >> 4) & 0x07]; - pin = 3 - ((addr & 0x01) << 1); - slot = ((addr & 0x06) >> 1); - if (irq >= 0) { - opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); - pci_set_irq_routing(pin + (slot << 2), irq); - pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07)); - } else { - opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); - pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); - } - opti822_update_irqs(dev, 1); - break; + case 0x88 ... 0x8f: + dev->pci_regs[addr] = val; + opti822_update_irqs(dev, 0); + irq = irq_map[val & 0x07]; + pin = 4 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!(val & 0x07)); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); + } + irq = irq_map[(val >> 4) & 0x07]; + pin = 3 - ((addr & 0x01) << 1); + slot = ((addr & 0x06) >> 1); + if (irq >= 0) { + opti822_log("Set IRQ routing: INT %c%c -> %02X\n", pin + 0x40, slot + 0x31, irq); + pci_set_irq_routing(pin + (slot << 2), irq); + pci_set_irq_level(pin + (slot << 2), !!((val >> 4) & 0x07)); + } else { + opti822_log("Set IRQ routing: INT %c%c -> FF\n", pin + 0x40, slot + 0x31); + pci_set_irq_routing(pin + (slot << 2), PCI_IRQ_DISABLED); + } + opti822_update_irqs(dev, 1); + break; } } @@ -327,7 +327,7 @@ static uint8_t opti822_pci_read(int func, int addr, void *priv) { opti822_t *dev = (opti822_t *) priv; - uint8_t ret; + uint8_t ret; ret = 0xff; @@ -343,12 +343,14 @@ static void opti822_reset(void *priv) { opti822_t *dev = (opti822_t *) priv; - int i; + int i; memset(dev->pci_regs, 0, 256); - dev->pci_regs[0x00] = 0x45; dev->pci_regs[0x01] = 0x10; /*OPTi*/ - dev->pci_regs[0x02] = 0x22; dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/ + dev->pci_regs[0x00] = 0x45; + dev->pci_regs[0x01] = 0x10; /*OPTi*/ + dev->pci_regs[0x02] = 0x22; + dev->pci_regs[0x03] = 0xc8; /*82C822 PCIB*/ dev->pci_regs[0x04] = 0x07; dev->pci_regs[0x06] = 0x80; dev->pci_regs[0x07] = 0x02; @@ -356,7 +358,8 @@ opti822_reset(void *priv) dev->pci_regs[0x0b] = 0x06; dev->pci_regs[0x0d] = 0x20; - dev->pci_regs[0x40] = 0x01; dev->pci_regs[0x41] = 0x0c; + dev->pci_regs[0x40] = 0x01; + dev->pci_regs[0x41] = 0x0c; dev->pci_regs[0x43] = 0x02; dev->pci_regs[0x52] = 0x06; dev->pci_regs[0x53] = 0x90; @@ -370,7 +373,7 @@ opti822_reset(void *priv) static void opti822_close(void *p) { - opti822_t *dev = (opti822_t *)p; + opti822_t *dev = (opti822_t *) p; free(dev); } diff --git a/src/device/hwm_gl518sm.c b/src/device/hwm_gl518sm.c index 3f8e836ad..730e2f2ce 100644 --- a/src/device/hwm_gl518sm.c +++ b/src/device/hwm_gl518sm.c @@ -279,8 +279,8 @@ gl518sm_init(const device_t *info) }, { /* voltages */ - hwm_get_vcore(), /* Vcore */ - RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the datasheet) */ + hwm_get_vcore(), /* Vcore */ + RESISTOR_DIVIDER(12000, 150, 47), /* +12V (15K/4.7K divider suggested in the datasheet) */ 3300, /* +3.3V */ 5000 /* +5V */ } diff --git a/src/device/hwm_lm78.c b/src/device/hwm_lm78.c index 4b1e65fb3..f7585945a 100644 --- a/src/device/hwm_lm78.c +++ b/src/device/hwm_lm78.c @@ -757,25 +757,25 @@ lm78_init(const device_t *info) hwm_values_t defaults = { { /* fan speeds */ - 3000, /* usually Chassis, sometimes CPU */ + 3000, /* usually Chassis, sometimes CPU */ 3000, /* usually CPU, sometimes Chassis */ 3000 /* usually PSU, sometimes Chassis */ }, { /* temperatures */ - 30, /* usually Board, sometimes Chassis */ - 30, /* Winbond only: usually CPU, sometimes Probe */ + 30, /* usually Board, sometimes Chassis */ + 30, /* Winbond only: usually CPU, sometimes Probe */ 30 /* Winbond only: usually CPU when not the one above */ }, { /* voltages */ - hwm_get_vcore(), /* Vcore */ - 0, /* sometimes Vtt, Vio or second CPU */ - 3300, /* +3.3V */ - RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ + hwm_get_vcore(), /* Vcore */ + 0, /* sometimes Vtt, Vio or second CPU */ + 3300, /* +3.3V */ + RESISTOR_DIVIDER(5000, 11, 16), /* +5V (divider values bruteforced) */ RESISTOR_DIVIDER(12000, 28, 10), /* +12V (28K/10K divider suggested in the W83781D datasheet) */ - LM78_NEG_VOLTAGE(12000, 2100), /* -12V */ - LM78_NEG_VOLTAGE(5000, 909), /* -5V */ + LM78_NEG_VOLTAGE(12000, 2100), /* -12V */ + LM78_NEG_VOLTAGE(5000, 909), /* -5V */ RESISTOR_DIVIDER(5000, 51, 75), /* W83782D/AS99127F only: +5VSB (5.1K/7.5K divider suggested in the datasheet) */ 3000, /* W83782D/AS99127F only: Vbat */ 2500, /* AS99127F only: +2.5V */ diff --git a/src/device/hwm_vt82c686.c b/src/device/hwm_vt82c686.c index 3b407e579..877138a4a 100644 --- a/src/device/hwm_vt82c686.c +++ b/src/device/hwm_vt82c686.c @@ -182,7 +182,7 @@ vt82c686_init(const device_t *info) /* Set default values. Since this hardware monitor has a complex voltage factor system, the values struct contains voltage values *before* applying their respective factors. */ hwm_values_t defaults = { -// clang-format on + // clang-format off { /* fan speeds */ 3000, /* usually CPU */ 3000 /* usually Chassis */ @@ -197,7 +197,7 @@ vt82c686_init(const device_t *info) 5000, /* +5V */ 12000 /* +12V */ } -// clang-format on + // clang-format on }; hwm_values = defaults; dev->values = &hwm_values; diff --git a/src/device/isamem.c b/src/device/isamem.c index 839f37f92..52327ad2c 100644 --- a/src/device/isamem.c +++ b/src/device/isamem.c @@ -1614,6 +1614,6 @@ isamem_get_from_internal_name(const char *s) const device_t * isamem_get_device(int board) { -/* Add the instance to the system. */ + /* Add the instance to the system. */ return boards[board].dev; } diff --git a/src/device/isartc.c b/src/device/isartc.c index 66accb66a..ad2b39f2f 100644 --- a/src/device/isartc.c +++ b/src/device/isartc.c @@ -763,7 +763,7 @@ isartc_get_from_internal_name(char *s) c++; } -/* Not found. */ + /* Not found. */ return (0); } diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index dcbfde9ed..f6d02a4d4 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -430,7 +430,7 @@ kbd_adddata(uint16_t val) /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ if (is_t1x00) { if (keyboard_recv(0x138) || keyboard_recv(0x11d)) { /* 'Fn' pressed */ - t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ + t1000_syskey(0x00, 0x04, 0x00); /* Set 'Fn' indicator */ switch (val) { case 0x45: /* Num Lock => toggle numpad */ t1000_syskey(0x00, 0x00, 0x10); @@ -515,8 +515,7 @@ static void kbd_write(uint16_t port, uint8_t val, void *priv) { xtkbd_t *kbd = (xtkbd_t *) priv; - uint8_t bit, set, new_clock; - + uint8_t bit, set, new_clock; switch (port) { case 0x61: /* Keyboard Control Register (aka Port B) */ @@ -532,7 +531,7 @@ kbd_write(uint16_t port, uint8_t val, void *priv) kbd->pb = val; if (!(kbd->pb & 0x80)) kbd->clock = !!(kbd->pb & 0x40); - ppi.pb = val; + ppi.pb = val; timer_process(); @@ -570,8 +569,8 @@ kbd_write(uint16_t port, uint8_t val, void *priv) case 0xc0 ... 0xcf: /* Pravetz Flags */ kbd_log("XTkbd: Port %02X out: %02X\n", port, val); if (kbd->type == KBD_TYPE_PRAVETZ) { - bit = (port >> 1) & 0x07; - set = (port & 0x01) << bit; + bit = (port >> 1) & 0x07; + set = (port & 0x01) << bit; kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set; } break; @@ -693,10 +692,10 @@ kbd_reset(void *priv) { xtkbd_t *kbd = (xtkbd_t *) priv; - kbd->want_irq = 0; - kbd->blocked = 0; - kbd->pa = 0x00; - kbd->pb = 0x00; + kbd->want_irq = 0; + kbd->blocked = 0; + kbd->pa = 0x00; + kbd->pb = 0x00; kbd->pravetz_flags = 0x00; keyboard_scan = 1; diff --git a/src/device/mouse_bus.c b/src/device/mouse_bus.c index 3eda32fda..802ae6d45 100644 --- a/src/device/mouse_bus.c +++ b/src/device/mouse_bus.c @@ -800,7 +800,7 @@ static const device_config_t ms_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mouse_logibus_device = { diff --git a/src/device/mouse_ps2.c b/src/device/mouse_ps2.c index d970fc11d..e7670b2fc 100644 --- a/src/device/mouse_ps2.c +++ b/src/device/mouse_ps2.c @@ -37,8 +37,8 @@ typedef struct { int mode; uint16_t flags; - uint8_t resolution; - uint8_t sample_rate; + uint8_t resolution; + uint8_t sample_rate; uint8_t command; @@ -84,7 +84,7 @@ mouse_clear_data(void *priv) static void ps2_report_coordinates(mouse_t *dev) { - uint8_t buff[3] = {0x08, 0x00, 0x00}; + uint8_t buff[3] = { 0x08, 0x00, 0x00 }; if (dev->x > 255) dev->x = 255; @@ -248,14 +248,13 @@ mouse_reset: dev->last_data[5] = val; if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 - && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0xc8 - && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50 - && mouse_get_buttons() == 5) { + && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0xc8 + && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50 + && mouse_get_buttons() == 5) { dev->flags |= FLAG_INTMODE | FLAG_5BTN; - } - else if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 - && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 - && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) { + } else if (dev->last_data[0] == 0xf3 && dev->last_data[1] == 0xc8 + && dev->last_data[2] == 0xf3 && dev->last_data[3] == 0x64 + && dev->last_data[4] == 0xf3 && dev->last_data[5] == 0x50) { dev->flags |= FLAG_INTMODE; } } @@ -264,7 +263,7 @@ mouse_reset: static int ps2_poll(int x, int y, int z, int b, void *priv) { - mouse_t *dev = (mouse_t *) priv; + mouse_t *dev = (mouse_t *) priv; if (!x && !y && !z && (b == dev->b)) return (0xff); @@ -310,7 +309,8 @@ mouse_ps2_init(const device_t *info) if (i > 2) dev->flags |= FLAG_INTELLI; - if (i == 4) i = 3; + if (i == 4) + i = 3; /* Hook into the general AT Keyboard driver. */ keyboard_at_set_mouse(ps2_write, dev); @@ -356,7 +356,7 @@ static const device_config_t ps2_config[] = { { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mouse_ps2_device = { diff --git a/src/device/mouse_serial.c b/src/device/mouse_serial.c index 01d03d0f3..2edc342e9 100644 --- a/src/device/mouse_serial.c +++ b/src/device/mouse_serial.c @@ -878,7 +878,7 @@ static const device_config_t ltsermouse_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mouse_mssystems_device = { diff --git a/src/device/serial.c b/src/device/serial.c index efb3cca4a..2434ca17c 100644 --- a/src/device/serial.c +++ b/src/device/serial.c @@ -51,7 +51,7 @@ enum { static int next_inst = 0; static serial_device_t serial_devices[SERIAL_MAX]; -//#define ENABLE_SERIAL_CONSOLE 1 +// #define ENABLE_SERIAL_CONSOLE 1 #ifdef ENABLE_SERIAL_LOG int serial_do_log = ENABLE_SERIAL_LOG; diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 12d0f4122..a306c5288 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1632,14 +1632,14 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time > xfer_time ? seek_time : xfer_time; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize > 0)) { - sec_count = ide->secount ? ide->secount : 256; + sec_count = ide->secount ? ide->secount : 256; if (sec_count > ide->blocksize) sec_count = ide->blocksize; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); wait_time = seek_time + xfer_time; } else if ((val == WIN_READ_MULTIPLE) && (ide->blocksize == 0)) - wait_time = 200.0; + wait_time = 200.0; else { sec_count = 1; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); @@ -1692,7 +1692,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_set_callback(ide, wait_time); } else if ((ide->type == IDE_HDD) && ((val == WIN_VERIFY) || (val == WIN_VERIFY_ONCE))) { uint32_t sec_count = ide->secount ? ide->secount : 256; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); ide_set_callback(ide, seek_time + ide_get_xfer_time(ide, 2)); } else if ((val == WIN_IDENTIFY) || (val == WIN_SET_FEATURES)) ide_callback(ide); @@ -1865,8 +1865,8 @@ ide_read_data(ide_t *ide, int length) uint32_t sec_count = ide->secount ? ide->secount : 256; if (sec_count > ide->blocksize) sec_count = ide->blocksize; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); - double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); + double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), sec_count); + double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); ide_set_callback(ide, seek_time + xfer_time); } else { ide_callback(ide); @@ -2166,7 +2166,7 @@ ide_callback(void *priv) ide_set_signature(ide); if (ide->type == IDE_ATAPI) { - ide->sc->error = 1; + ide->sc->error = 1; if (ide->device_reset) ide->device_reset(ide->sc); if (ide->sc->pad0) /* pad0 = early */ diff --git a/src/disk/hdc_st506_xt.c b/src/disk/hdc_st506_xt.c index 89a921c5a..f130a58d5 100644 --- a/src/disk/hdc_st506_xt.c +++ b/src/disk/hdc_st506_xt.c @@ -100,12 +100,12 @@ #define ST506_XT_TYPE_VICTOR_V86P 27 #define ST506_XT_TYPE_TOSHIBA_T1200 28 -#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" -#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" -#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" -#define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" -#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" -#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define XEBEC_BIOS_FILE "roms/hdd/st506/ibm_xebec_62x0822_1985.bin" +#define DTC_BIOS_FILE "roms/hdd/st506/dtc_cxd21a.bin" +#define ST11_BIOS_FILE_OLD "roms/hdd/st506/st11_bios_vers_1.7.bin" +#define ST11_BIOS_FILE_NEW "roms/hdd/st506/st11_bios_vers_2.0.bin" +#define WD1002A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" +#define WD1004A_WX1_BIOS_FILE "roms/hdd/st506/wd1002a_wx1-62-000094-032.bin" /* SuperBIOS was for both the WX1 and 27X, users jumpers readout to determine if to use 26 sectors per track, 26 -> 17 sectors per track translation, or 17 sectors per track. */ @@ -292,13 +292,16 @@ typedef struct { } hd_type_t; hd_type_t hd_types[4] = { + // clang-format off { 306, 4, MFM_SECTORS}, /* type 0 */ { 612, 4, MFM_SECTORS}, /* type 16 */ { 615, 4, MFM_SECTORS}, /* type 2 */ { 306, 8, MFM_SECTORS} /* type 13 */ + // clang-format on }; hd_type_t hd_types_olivetti[16] = { + // clang-format off { 697, 5, MFM_SECTORS}, { 612, 4, MFM_SECTORS}, /* type 16 */ { 612, 4, MFM_SECTORS}, /* type 16 */ @@ -315,6 +318,7 @@ hd_type_t hd_types_olivetti[16] = { { 612, 4, MFM_SECTORS}, /* type 16 */ { 612, 4, MFM_SECTORS}, /* type 16 */ { 306, 4, MFM_SECTORS} /* "not present" with the second hard disk */ + // clang-format on }; #ifdef ENABLE_ST506_XT_LOG @@ -1291,9 +1295,9 @@ mem_write(uint32_t addr, uint8_t val, void *priv) addr -= dev->bios_addr; switch (dev->type) { - case ST506_XT_TYPE_ST11M: /* ST-11M */ - case ST506_XT_TYPE_ST11R: /* ST-11R */ - mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ + mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; default: @@ -1341,9 +1345,9 @@ mem_read(uint32_t addr, void *priv) } break; - case ST506_XT_TYPE_ST11M: /* ST-11M */ - case ST506_XT_TYPE_ST11R: /* ST-11R */ - mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ + case ST506_XT_TYPE_ST11M: /* ST-11M */ + case ST506_XT_TYPE_ST11R: /* ST-11R */ + mask = 0x1fff; /* ST-11 decodes RAM on each 8K block */ break; /* default: @@ -1636,7 +1640,7 @@ st506_init(const device_t *info) break; case ST506_XT_TYPE_TOSHIBA_T1200: /* Toshiba T1200 */ - fn = NULL; + fn = NULL; dev->base = 0x01f0; dev->switches = 0x0c; break; diff --git a/src/disk/hdd.c b/src/disk/hdd.c index 2e769dbdf..61a355b44 100644 --- a/src/disk/hdd.c +++ b/src/disk/hdd.c @@ -419,21 +419,16 @@ hdd_zones_init(hard_disk_t *hdd) } static hdd_preset_t hdd_speed_presets[] = { - {.name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32}, - - { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, - - { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, - - { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, - - { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, - - { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, - - { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, - - { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + // clang-format off + { .name = "RAM Disk (max. speed)", .internal_name = "ramdisk", .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[1989] 3500 RPM", .internal_name = "1989_3500rpm", .zones = 1, .avg_spt = 35, .heads = 2, .rpm = 3500, .full_stroke_ms = 40, .track_seek_ms = 8, .rcache_num_seg = 1, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1992] 3600 RPM", .internal_name = "1992_3600rpm", .zones = 1, .avg_spt = 45, .heads = 2, .rpm = 3600, .full_stroke_ms = 30, .track_seek_ms = 6, .rcache_num_seg = 4, .rcache_seg_size = 16, .max_multiple = 8 }, + { .name = "[1994] 4500 RPM", .internal_name = "1994_4500rpm", .zones = 8, .avg_spt = 80, .heads = 4, .rpm = 4500, .full_stroke_ms = 26, .track_seek_ms = 5, .rcache_num_seg = 4, .rcache_seg_size = 32, .max_multiple = 16 }, + { .name = "[1996] 5400 RPM", .internal_name = "1996_5400rpm", .zones = 16, .avg_spt = 135, .heads = 4, .rpm = 5400, .full_stroke_ms = 24, .track_seek_ms = 3, .rcache_num_seg = 4, .rcache_seg_size = 64, .max_multiple = 16 }, + { .name = "[1997] 5400 RPM", .internal_name = "1997_5400rpm", .zones = 16, .avg_spt = 185, .heads = 6, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2.5, .rcache_num_seg = 8, .rcache_seg_size = 64, .max_multiple = 32 }, + { .name = "[1998] 5400 RPM", .internal_name = "1998_5400rpm", .zones = 16, .avg_spt = 300, .heads = 8, .rpm = 5400, .full_stroke_ms = 20, .track_seek_ms = 2, .rcache_num_seg = 8, .rcache_seg_size = 128, .max_multiple = 32 }, + { .name = "[2000] 7200 RPM", .internal_name = "2000_7200rpm", .zones = 16, .avg_spt = 350, .heads = 6, .rpm = 7200, .full_stroke_ms = 15, .track_seek_ms = 2, .rcache_num_seg = 16, .rcache_seg_size = 128, .max_multiple = 32 }, + // clang-format on }; int diff --git a/src/disk/hdd_table.c b/src/disk/hdd_table.c index f3f1ee2d1..d75dc7e8d 100644 --- a/src/disk/hdd_table.c +++ b/src/disk/hdd_table.c @@ -170,5 +170,5 @@ unsigned int hdd_table[128][3] = { { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } -// clang-format on + // clang-format on }; diff --git a/src/floppy/fdc.c b/src/floppy/fdc.c index ff75b6c70..fbc95be8a 100644 --- a/src/floppy/fdc.c +++ b/src/floppy/fdc.c @@ -2373,17 +2373,17 @@ const device_t fdc_xt_device = { }; const device_t fdc_xt_sec_device = { - .name = "PC/XT Floppy Drive Controller (Secondary)", + .name = "PC/XT Floppy Drive Controller (Secondary)", .internal_name = "fdc_xt", - .flags = FDC_FLAG_SEC, - .local = 0, - .init = fdc_init, - .close = fdc_close, - .reset = fdc_reset, + .flags = FDC_FLAG_SEC, + .local = 0, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t fdc_xt_t1x00_device = { @@ -2457,17 +2457,17 @@ const device_t fdc_at_device = { }; const device_t fdc_at_sec_device = { - .name = "PC/AT Floppy Drive Controller (Secondary)", + .name = "PC/AT Floppy Drive Controller (Secondary)", .internal_name = "fdc_at_sec", - .flags = 0, - .local = FDC_FLAG_AT | FDC_FLAG_SEC, - .init = fdc_init, - .close = fdc_close, - .reset = fdc_reset, + .flags = 0, + .local = FDC_FLAG_AT | FDC_FLAG_SEC, + .init = fdc_init, + .close = fdc_close, + .reset = fdc_reset, { .available = NULL }, .speed_changed = NULL, - .force_redraw = NULL, - .config = NULL + .force_redraw = NULL, + .config = NULL }; const device_t fdc_at_actlow_device = { diff --git a/src/floppy/fdc_magitronic.c b/src/floppy/fdc_magitronic.c index 1b22404de..d71721d7b 100644 --- a/src/floppy/fdc_magitronic.c +++ b/src/floppy/fdc_magitronic.c @@ -124,7 +124,7 @@ static const device_config_t b215_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t fdc_b215_device = { diff --git a/src/floppy/fdc_pii15xb.c b/src/floppy/fdc_pii15xb.c index d8b687502..be471face 100644 --- a/src/floppy/fdc_pii15xb.c +++ b/src/floppy/fdc_pii15xb.c @@ -140,7 +140,7 @@ static const device_config_t pii_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t fdc_pii151b_device = { diff --git a/src/floppy/fdd.c b/src/floppy/fdd.c index 93e96d5eb..a6ccb6da5 100644 --- a/src/floppy/fdd.c +++ b/src/floppy/fdd.c @@ -75,7 +75,7 @@ typedef struct { fdd_t fdd[FDD_NUM]; -char floppyfns[FDD_NUM][512]; +char floppyfns[FDD_NUM][512]; char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; pc_timer_t fdd_poll_time[FDD_NUM]; diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index 9133c4834..3ebfeefd9 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -40,30 +40,29 @@ #include <86box/fdd_img.h> #include <86box/fdc.h> - typedef struct { - FILE *f; - uint8_t track_data[2][50000]; - int sectors, tracks, sides; - uint8_t sector_size; - int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ - int dmf; - int track; - int track_width; - uint32_t base; - uint8_t gap2_size; - uint8_t gap3_size; - uint16_t disk_flags; - uint16_t track_flags; - uint8_t sector_pos_side[256][256]; - uint16_t sector_pos[256][256]; - uint8_t current_sector_pos_side; - uint16_t current_sector_pos; - uint8_t *disk_data; - uint8_t is_cqm; - uint8_t disk_at_once; - uint8_t interleave; - uint8_t skew; + FILE *f; + uint8_t track_data[2][50000]; + int sectors, tracks, sides; + uint8_t sector_size; + int xdf_type; /* 0 = not XDF, 1-5 = one of the five XDF types */ + int dmf; + int track; + int track_width; + uint32_t base; + uint8_t gap2_size; + uint8_t gap3_size; + uint16_t disk_flags; + uint16_t track_flags; + uint8_t sector_pos_side[256][256]; + uint16_t sector_pos[256][256]; + uint8_t current_sector_pos_side; + uint16_t current_sector_pos; + uint8_t *disk_data; + uint8_t is_cqm; + uint8_t disk_at_once; + uint8_t interleave; + uint8_t skew; } img_t; @@ -289,162 +288,153 @@ int img_do_log = ENABLE_IMG_LOG; static void img_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (img_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (img_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define img_log(fmt, ...) +# define img_log(fmt, ...) #endif - /* Generic */ static int sector_size_code(int sector_size) { - switch(sector_size) { - case 128: - return(0); + switch (sector_size) { + case 128: + return (0); - case 256: - return(1); + case 256: + return (1); - default: - case 512: - return(2); + default: + case 512: + return (2); - case 1024: - return(3); + case 1024: + return (3); - case 2048: - return(4); + case 2048: + return (4); - case 4096: - return(5); + case 4096: + return (5); - case 8192: - return(6); + case 8192: + return (6); - case 16384: - return(7); + case 16384: + return (7); } } - static int bps_is_valid(uint16_t bps) { int i; for (i = 0; i <= 8; i++) { - if (bps == (128 << i)) return(1); + if (bps == (128 << i)) + return (1); } - return(0); + return (0); } - static int first_byte_is_valid(uint8_t first_byte) { - switch(first_byte) { - case 0x60: - case 0xE9: - case 0xEB: - return(1); + switch (first_byte) { + case 0x60: + case 0xE9: + case 0xEB: + return (1); - default: - break; + default: + break; } - return(0); + return (0); } - -#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] +#define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] #define xdf_disk_sector xdf_disk_layout[current_xdft][!is_t0][array_sector] - static int interleave(int sector, int skew, int track_spt) { uint32_t skewed_i; uint32_t adjusted_r; - uint32_t add = (track_spt & 1); + uint32_t add = (track_spt & 1); uint32_t adjust = (track_spt >> 1); - skewed_i = (sector + skew) % track_spt; + skewed_i = (sector + skew) % track_spt; adjusted_r = (skewed_i >> 1) + 1; if (skewed_i & 1) - adjusted_r += (adjust + add); + adjusted_r += (adjust + add); - return(adjusted_r); + return (adjusted_r); } - static void write_back(int drive) { - img_t *dev = img[drive]; - int ssize = 128 << ((int) dev->sector_size); - int side, size; + img_t *dev = img[drive]; + int ssize = 128 << ((int) dev->sector_size); + int side, size; - if (dev->f == NULL) return; + if (dev->f == NULL) + return; - if (dev->disk_at_once) return; + if (dev->disk_at_once) + return; if (fseek(dev->f, dev->base + (dev->track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) - pclog("IMG write_back(): Error seeking to the beginning of the file\n"); + pclog("IMG write_back(): Error seeking to the beginning of the file\n"); for (side = 0; side < dev->sides; side++) { - size = dev->sectors * ssize; - if (fwrite(dev->track_data[side], 1, size, dev->f) != size) - fatal("IMG write_back(): Error writing data\n"); + size = dev->sectors * ssize; + if (fwrite(dev->track_data[side], 1, size, dev->f) != size) + fatal("IMG write_back(): Error writing data\n"); } } - static uint16_t disk_flags(int drive) { img_t *dev = img[drive]; - return(dev->disk_flags); + return (dev->disk_flags); } - static uint16_t side_flags(int drive) { img_t *dev = img[drive]; - return(dev->track_flags); + return (dev->track_flags); } - static void set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { img_t *dev = img[drive]; dev->current_sector_pos_side = dev->sector_pos_side[h][r]; - dev->current_sector_pos = dev->sector_pos[h][r]; + dev->current_sector_pos = dev->sector_pos[h][r]; } - static uint8_t poll_read_data(int drive, int side, uint16_t pos) { img_t *dev = img[drive]; - return(dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); + return (dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos]); } - static void poll_write_data(int drive, int side, uint16_t pos, uint8_t data) { @@ -453,56 +443,55 @@ poll_write_data(int drive, int side, uint16_t pos, uint8_t data) dev->track_data[dev->current_sector_pos_side][dev->current_sector_pos + pos] = data; } - static int format_conditions(int drive) { - img_t *dev = img[drive]; - int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); + img_t *dev = img[drive]; + int temp = (fdc_get_format_sectors(img_fdc) == dev->sectors); temp = temp && (fdc_get_format_n(img_fdc) == dev->sector_size); temp = temp && (dev->xdf_type == 0); - return(temp); + return (temp); } - static void img_seek(int drive, int track) { - img_t *dev = img[drive]; - int side; - int current_xdft = dev->xdf_type - 1; - int read_bytes = 0; - uint8_t id[4] = { 0, 0, 0, 0 }; - int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; - int ssize = 128 << ((int) dev->sector_size); + img_t *dev = img[drive]; + int side; + int current_xdft = dev->xdf_type - 1; + int read_bytes = 0; + uint8_t id[4] = { 0, 0, 0, 0 }; + int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; + int ssize = 128 << ((int) dev->sector_size); uint32_t cur_pos = 0; - if (dev->f == NULL) return; + if (dev->f == NULL) + return; if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; + track /= 2; dev->track = track; d86f_set_cur_track(drive, track); is_t0 = (track == 0) ? 1 : 0; - if (! dev->disk_at_once) { - if (fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) - fatal("img_seek(): Error seeking\n"); + if (!dev->disk_at_once) { + if (fseek(dev->f, dev->base + (track * dev->sectors * ssize * dev->sides), SEEK_SET) == -1) + fatal("img_seek(): Error seeking\n"); } for (side = 0; side < dev->sides; side++) { - if (dev->disk_at_once) { - cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); - memcpy(dev->track_data[side], dev->disk_data + cur_pos, dev->sectors * ssize); - } else { - read_bytes = fread(dev->track_data[side], 1, dev->sectors * ssize, dev->f); - if (read_bytes < (dev->sectors * ssize)) - memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); - } + if (dev->disk_at_once) { + cur_pos = (track * dev->sectors * ssize * dev->sides) + (side * dev->sectors * ssize); + memcpy(dev->track_data[side], dev->disk_data + cur_pos, dev->sectors * ssize); + } else { + read_bytes = fread(dev->track_data[side], 1, dev->sectors * ssize, dev->f); + if (read_bytes < (dev->sectors * ssize)) + memset(dev->track_data[side] + read_bytes, 0xf6, (dev->sectors * ssize) - read_bytes); + } } d86f_reset_index_hole_pos(drive, 0); @@ -512,136 +501,134 @@ img_seek(int drive, int track) d86f_destroy_linked_lists(drive, 1); if (track > dev->tracks) { - d86f_zero_track(drive); - return; + d86f_zero_track(drive); + return; } if (!dev->xdf_type || dev->is_cqm) { - for (side = 0; side < dev->sides; side++) { - current_pos = d86f_prepare_pretrack(drive, side, 0); + for (side = 0; side < dev->sides; side++) { + current_pos = d86f_prepare_pretrack(drive, side, 0); - for (sector = 0; sector < dev->sectors; sector++) { - if (dev->is_cqm) { - if (dev->interleave) - sr = interleave(sector, dev->skew, dev->sectors); - else { - sr = sector + 1; - sr += dev->skew; - if (sr > dev->sectors) - sr -= dev->sectors; - } - } else { - if (dev->gap3_size < 68) - sr = interleave(sector, 1, dev->sectors); - else - sr = dev->dmf ? (dmf_r[sector]) : (sector + 1); - } - id[0] = track; - id[1] = side; - id[2] = sr; - id[3] = dev->sector_size; - dev->sector_pos_side[side][sr] = side; - dev->sector_pos[side][sr] = (sr - 1) * ssize; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[side][(sr - 1) * ssize], ssize, dev->gap2_size, dev->gap3_size, 0); + for (sector = 0; sector < dev->sectors; sector++) { + if (dev->is_cqm) { + if (dev->interleave) + sr = interleave(sector, dev->skew, dev->sectors); + else { + sr = sector + 1; + sr += dev->skew; + if (sr > dev->sectors) + sr -= dev->sectors; + } + } else { + if (dev->gap3_size < 68) + sr = interleave(sector, 1, dev->sectors); + else + sr = dev->dmf ? (dmf_r[sector]) : (sector + 1); + } + id[0] = track; + id[1] = side; + id[2] = sr; + id[3] = dev->sector_size; + dev->sector_pos_side[side][sr] = side; + dev->sector_pos[side][sr] = (sr - 1) * ssize; + current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[side][(sr - 1) * ssize], ssize, dev->gap2_size, dev->gap3_size, 0); - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } } else { - total = dev->sectors; - img_pos = 0; - sside = 0; + total = dev->sectors; + img_pos = 0; + sside = 0; - /* Pass 1, get sector positions in the image. */ - for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) { - if (is_t0) { - img_pos = (sector % total) << 9; - sside = (sector >= total) ? 1 : 0; - } + /* Pass 1, get sector positions in the image. */ + for (sector = 0; sector < xdf_logical_sectors[current_xdft][!is_t0]; sector++) { + if (is_t0) { + img_pos = (sector % total) << 9; + sside = (sector >= total) ? 1 : 0; + } - if (xdf_img_sector.word) { - dev->sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; - dev->sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; - } + if (xdf_img_sector.word) { + dev->sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; + dev->sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; + } - if (! is_t0) { - img_pos += (128 << (xdf_img_sector.id.r & 7)); - if (img_pos >= (total << 9)) sside = 1; - img_pos %= (total << 9); - } - } + if (!is_t0) { + img_pos += (128 << (xdf_img_sector.id.r & 7)); + if (img_pos >= (total << 9)) + sside = 1; + img_pos %= (total << 9); + } + } - /* Pass 2, prepare the actual track. */ - for (side = 0; side < dev->sides; side++) { - current_pos = d86f_prepare_pretrack(drive, side, 0); + /* Pass 2, prepare the actual track. */ + for (side = 0; side < dev->sides; side++) { + current_pos = d86f_prepare_pretrack(drive, side, 0); - for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { - array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; - buf_side = dev->sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - buf_pos = dev->sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; + for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { + array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; + buf_side = dev->sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; + buf_pos = dev->sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - id[0] = track; - id[1] = xdf_disk_sector.id.h; - id[2] = xdf_disk_sector.id.r; + id[0] = track; + id[1] = xdf_disk_sector.id.h; + id[2] = xdf_disk_sector.id.r; - if (is_t0) { - id[3] = 2; - current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); - } else { - id[3] = id[2] & 7; - ssize = (128 << id[3]); - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); - } + if (is_t0) { + id[3] = 2; + current_pos = d86f_prepare_sector(drive, side, current_pos, id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); + } else { + id[3] = id[2] & 7; + ssize = (128 << id[3]); + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &dev->track_data[buf_side][buf_pos], ssize, dev->gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0); + } - if (sector == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - } - } + if (sector == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + } + } } } - void img_init(void) { memset(img, 0x00, sizeof(img)); } - int is_divisible(uint16_t total, uint8_t what) { if ((total != 0) && (what != 0)) - return ((total % what) == 0); + return ((total % what) == 0); else - return 0; + return 0; } - void img_load(int drive, char *fn) { uint16_t bpb_bps; uint16_t bpb_total; - uint8_t bpb_mid; /* Media type ID. */ - uint8_t bpb_sectors; - uint8_t bpb_sides; - uint8_t cqm, ddi, fdf, fdi; + uint8_t bpb_mid; /* Media type ID. */ + uint8_t bpb_sectors; + uint8_t bpb_sides; + uint8_t cqm, ddi, fdf, fdi; uint16_t comment_len = 0; - int16_t block_len = 0; - uint32_t cur_pos = 0; - uint8_t rep_byte = 0; - uint8_t run = 0; - uint8_t real_run = 0; + int16_t block_len = 0; + uint32_t cur_pos = 0; + uint8_t rep_byte = 0; + uint8_t run = 0; + uint8_t real_run = 0; uint8_t *bpos; uint16_t track_bytes = 0; uint8_t *literal; - img_t *dev; - int temp_rate; - int guess = 0; - int size; - int i; + img_t *dev; + int temp_rate; + int guess = 0; + int size; + int i; ext = path_get_extension(fn); @@ -650,568 +637,572 @@ img_load(int drive, char *fn) writeprot[drive] = 0; /* Allocate a drive block. */ - dev = (img_t *)malloc(sizeof(img_t)); + dev = (img_t *) malloc(sizeof(img_t)); memset(dev, 0x00, sizeof(img_t)); dev->f = plat_fopen(fn, "rb+"); if (dev->f == NULL) { - dev->f = plat_fopen(fn, "rb"); - if (dev->f == NULL) { - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } - writeprot[drive] = 1; + dev->f = plat_fopen(fn, "rb"); + if (dev->f == NULL) { + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } + writeprot[drive] = 1; } if (ui_writeprot[drive]) - writeprot[drive] = 1; + writeprot[drive] = 1; fwriteprot[drive] = writeprot[drive]; cqm = ddi = fdf = fdi = 0; dev->interleave = dev->skew = 0; - if (! strcasecmp(ext, "DDI")) { - ddi = 1; - dev->base = 0x2400; + if (!strcasecmp(ext, "DDI")) { + ddi = 1; + dev->base = 0x2400; } else - dev->base = 0; + dev->base = 0; - if (! strcasecmp(ext, "FDI")) { - /* This is a Japanese FDI image, so let's read the header */ - img_log("img_load(): File is a Japanese FDI image...\n"); - fseek(dev->f, 0x10, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, 0x0C, SEEK_SET); - (void) !fread(&size, 1, 4, dev->f); - bpb_total = size / bpb_bps; - fseek(dev->f, 0x08, SEEK_SET); - (void) !fread(&(dev->base), 1, 4, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - if (bpb_mid < 0xF0) - bpb_mid = 0xF0; - fseek(dev->f, 0x14, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x18, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, dev->base, SEEK_SET); - first_byte = fgetc(dev->f); + if (!strcasecmp(ext, "FDI")) { + /* This is a Japanese FDI image, so let's read the header */ + img_log("img_load(): File is a Japanese FDI image...\n"); + fseek(dev->f, 0x10, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, 0x0C, SEEK_SET); + (void) !fread(&size, 1, 4, dev->f); + bpb_total = size / bpb_bps; + fseek(dev->f, 0x08, SEEK_SET); + (void) !fread(&(dev->base), 1, 4, dev->f); + fseek(dev->f, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->f); + if (bpb_mid < 0xF0) + bpb_mid = 0xF0; + fseek(dev->f, 0x14, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x18, SEEK_SET); + bpb_sides = fgetc(dev->f); + fseek(dev->f, dev->base, SEEK_SET); + first_byte = fgetc(dev->f); - fdi = 1; - cqm = 0; - dev->disk_at_once = 0; - fdf = 0; + fdi = 1; + cqm = 0; + dev->disk_at_once = 0; + fdf = 0; } else { - /* Read the first four bytes. */ - fseek(dev->f, 0x00, SEEK_SET); - first_byte = fgetc(dev->f); - fseek(dev->f, 0x01, SEEK_SET); - second_byte = fgetc(dev->f); - fseek(dev->f, 0x02, SEEK_SET); - third_byte = fgetc(dev->f); - fseek(dev->f, 0x03, SEEK_SET); - fourth_byte = fgetc(dev->f); + /* Read the first four bytes. */ + fseek(dev->f, 0x00, SEEK_SET); + first_byte = fgetc(dev->f); + fseek(dev->f, 0x01, SEEK_SET); + second_byte = fgetc(dev->f); + fseek(dev->f, 0x02, SEEK_SET); + third_byte = fgetc(dev->f); + fseek(dev->f, 0x03, SEEK_SET); + fourth_byte = fgetc(dev->f); - if ((first_byte == 0x1A) && (second_byte == 'F') && - (third_byte == 'D') && (fourth_byte == 'F')) { - /* This is a FDF image. */ - img_log("img_load(): File is a FDF image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, "rb"); + if ((first_byte == 0x1A) && (second_byte == 'F') && (third_byte == 'D') && (fourth_byte == 'F')) { + /* This is a FDF image. */ + img_log("img_load(): File is a FDF image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(dev->f); + dev->f = plat_fopen(fn, "rb"); - fdf = 1; - cqm = 0; - dev->disk_at_once = 1; + fdf = 1; + cqm = 0; + dev->disk_at_once = 1; - fseek(dev->f, 0x50, SEEK_SET); - (void) !fread(&dev->tracks, 1, 4, dev->f); + fseek(dev->f, 0x50, SEEK_SET); + (void) !fread(&dev->tracks, 1, 4, dev->f); - /* Decode the entire file - pass 1, no write to buffer, determine length. */ - fseek(dev->f, 0x80, SEEK_SET); - size = 0; - track_bytes = 0; - bpos = dev->disk_data; - while (! feof(dev->f)) { - if (! track_bytes) { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("%04X\n", track_bytes); - } + /* Decode the entire file - pass 1, no write to buffer, determine length. */ + fseek(dev->f, 0x80, SEEK_SET); + size = 0; + track_bytes = 0; + bpos = dev->disk_data; + while (!feof(dev->f)) { + if (!track_bytes) { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(dev->f); + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("%04X\n", track_bytes); + } - if (feof(dev->f)) break; + if (feof(dev->f)) + break; - if (first_byte == 0xFF) break; + if (first_byte == 0xFF) + break; - if (first_byte) { - run = fgetc(dev->f); + if (first_byte) { + run = fgetc(dev->f); - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; - if (run & 0x80) { - /* Repeat. */ - track_bytes--; - rep_byte = fgetc(dev->f); - } else { - /* Literal. */ - track_bytes -= (run & 0x7f); - literal = (uint8_t *)malloc(run & 0x7f); - (void) !fread(literal, 1, (run & 0x7f), dev->f); - free(literal); - } - size += (run & 0x7f); - if (!track_bytes) - size -= fdf_suppress_final_byte; - } else { - /* Literal block. */ - size += (track_bytes - fdf_suppress_final_byte); - literal = (uint8_t *)malloc(track_bytes); - (void) !fread(literal, 1, track_bytes, dev->f); - free(literal); - track_bytes = 0; - } + if (run & 0x80) { + /* Repeat. */ + track_bytes--; + rep_byte = fgetc(dev->f); + } else { + /* Literal. */ + track_bytes -= (run & 0x7f); + literal = (uint8_t *) malloc(run & 0x7f); + (void) !fread(literal, 1, (run & 0x7f), dev->f); + free(literal); + } + size += (run & 0x7f); + if (!track_bytes) + size -= fdf_suppress_final_byte; + } else { + /* Literal block. */ + size += (track_bytes - fdf_suppress_final_byte); + literal = (uint8_t *) malloc(track_bytes); + (void) !fread(literal, 1, track_bytes, dev->f); + free(literal); + track_bytes = 0; + } - if (feof(dev->f)) break; - } + if (feof(dev->f)) + break; + } - /* Allocate the buffer. */ - dev->disk_data = (uint8_t *)malloc(size); + /* Allocate the buffer. */ + dev->disk_data = (uint8_t *) malloc(size); - /* Decode the entire file - pass 2, write to buffer. */ - fseek(dev->f, 0x80, SEEK_SET); - track_bytes = 0; - bpos = dev->disk_data; - while(! feof(dev->f)) { - if (! track_bytes) { - /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ - first_byte = fgetc(dev->f); - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("Block header: %02X %04X ", first_byte, track_bytes); - /* Read the length of encoded data block. */ - (void) !fread(&track_bytes, 1, 2, dev->f); - img_log("%04X\n", track_bytes); - } + /* Decode the entire file - pass 2, write to buffer. */ + fseek(dev->f, 0x80, SEEK_SET); + track_bytes = 0; + bpos = dev->disk_data; + while (!feof(dev->f)) { + if (!track_bytes) { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(dev->f); + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + (void) !fread(&track_bytes, 1, 2, dev->f); + img_log("%04X\n", track_bytes); + } - if (feof(dev->f)) break; + if (feof(dev->f)) + break; - if (first_byte == 0xFF) break; + if (first_byte == 0xFF) + break; - if (first_byte) { - run = fgetc(dev->f); - real_run = (run & 0x7f); + if (first_byte) { + run = fgetc(dev->f); + real_run = (run & 0x7f); - /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ - track_bytes--; + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; - if (run & 0x80) { - /* Repeat. */ - track_bytes--; - if (! track_bytes) - real_run -= fdf_suppress_final_byte; - rep_byte = fgetc(dev->f); - if (real_run) - memset(bpos, rep_byte, real_run); - } else { - /* Literal. */ - track_bytes -= real_run; - literal = (uint8_t *) malloc(real_run); - (void) !fread(literal, 1, real_run, dev->f); - if (! track_bytes) - real_run -= fdf_suppress_final_byte; - if (run & 0x7f) - memcpy(bpos, literal, real_run); - free(literal); - } - bpos += real_run; - } else { - /* Literal block. */ - literal = (uint8_t *) malloc(track_bytes); - (void) !fread(literal, 1, track_bytes, dev->f); - memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); - free(literal); - bpos += (track_bytes - fdf_suppress_final_byte); - track_bytes = 0; - } + if (run & 0x80) { + /* Repeat. */ + track_bytes--; + if (!track_bytes) + real_run -= fdf_suppress_final_byte; + rep_byte = fgetc(dev->f); + if (real_run) + memset(bpos, rep_byte, real_run); + } else { + /* Literal. */ + track_bytes -= real_run; + literal = (uint8_t *) malloc(real_run); + (void) !fread(literal, 1, real_run, dev->f); + if (!track_bytes) + real_run -= fdf_suppress_final_byte; + if (run & 0x7f) + memcpy(bpos, literal, real_run); + free(literal); + } + bpos += real_run; + } else { + /* Literal block. */ + literal = (uint8_t *) malloc(track_bytes); + (void) !fread(literal, 1, track_bytes, dev->f); + memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); + free(literal); + bpos += (track_bytes - fdf_suppress_final_byte); + track_bytes = 0; + } - if (feof(dev->f)) break; - } + if (feof(dev->f)) + break; + } - first_byte = *dev->disk_data; + first_byte = *dev->disk_data; - bpb_bps = *(uint16_t *)(dev->disk_data + 0x0B); - bpb_total = *(uint16_t *)(dev->disk_data + 0x13); - bpb_mid = *(dev->disk_data + 0x15); - bpb_sectors = *(dev->disk_data + 0x18); - bpb_sides = *(dev->disk_data + 0x1A); + bpb_bps = *(uint16_t *) (dev->disk_data + 0x0B); + bpb_total = *(uint16_t *) (dev->disk_data + 0x13); + bpb_mid = *(dev->disk_data + 0x15); + bpb_sectors = *(dev->disk_data + 0x18); + bpb_sides = *(dev->disk_data + 0x1A); - /* Jump ahead to determine the image's geometry. */ - goto jump_if_fdf; - } + /* Jump ahead to determine the image's geometry. */ + goto jump_if_fdf; + } - if (((first_byte == 'C') && (second_byte == 'Q')) || - ((first_byte == 'c') && (second_byte == 'q'))) { - img_log("img_load(): File is a CopyQM image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - fclose(dev->f); - dev->f = plat_fopen(fn, "rb"); + if (((first_byte == 'C') && (second_byte == 'Q')) || ((first_byte == 'c') && (second_byte == 'q'))) { + img_log("img_load(): File is a CopyQM image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(dev->f); + dev->f = plat_fopen(fn, "rb"); - fseek(dev->f, 0x03, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, 0x03, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->f); #if 0 fseek(dev->f, 0x0B, SEEK_SET); (void) !fread(&bpb_total, 1, 2, dev->f); #endif - fseek(dev->f, 0x10, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, 0x12, SEEK_SET); - bpb_sides = fgetc(dev->f); - fseek(dev->f, 0x5B, SEEK_SET); - dev->tracks = fgetc(dev->f); + fseek(dev->f, 0x10, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, 0x12, SEEK_SET); + bpb_sides = fgetc(dev->f); + fseek(dev->f, 0x5B, SEEK_SET); + dev->tracks = fgetc(dev->f); - bpb_total = ((uint16_t)bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; + bpb_total = ((uint16_t) bpb_sectors) * ((uint16_t) bpb_sides) * dev->tracks; - fseek(dev->f, 0x74, SEEK_SET); - dev->interleave = fgetc(dev->f); - fseek(dev->f, 0x76, SEEK_SET); - dev->skew = fgetc(dev->f); + fseek(dev->f, 0x74, SEEK_SET); + dev->interleave = fgetc(dev->f); + fseek(dev->f, 0x76, SEEK_SET); + dev->skew = fgetc(dev->f); - dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + dev->disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - fseek(dev->f, 0x6F, SEEK_SET); - (void) !fread(&comment_len, 1, 2, dev->f); + fseek(dev->f, 0x6F, SEEK_SET); + (void) !fread(&comment_len, 1, 2, dev->f); - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; + fseek(dev->f, -1, SEEK_END); + size = ftell(dev->f) + 1; - fseek(dev->f, 133 + comment_len, SEEK_SET); + fseek(dev->f, 133 + comment_len, SEEK_SET); - cur_pos = 0; + cur_pos = 0; - while(! feof(dev->f)) { - (void) !fread(&block_len, 1, 2, dev->f); + while (!feof(dev->f)) { + (void) !fread(&block_len, 1, 2, dev->f); - if (! feof(dev->f)) { - if (block_len < 0) { - rep_byte = fgetc(dev->f); - block_len = -block_len; - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - memset(dev->disk_data + cur_pos, rep_byte, block_len); - break; - } else { - memset(dev->disk_data + cur_pos, rep_byte, block_len); - cur_pos += block_len; - } - } else if (block_len > 0) { - if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { - block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); - break; - } else { - (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); - cur_pos += block_len; - } - } - } - } - img_log("Finished reading CopyQM image data\n"); + if (!feof(dev->f)) { + if (block_len < 0) { + rep_byte = fgetc(dev->f); + block_len = -block_len; + if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { + block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; + memset(dev->disk_data + cur_pos, rep_byte, block_len); + break; + } else { + memset(dev->disk_data + cur_pos, rep_byte, block_len); + cur_pos += block_len; + } + } else if (block_len > 0) { + if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { + block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; + (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + break; + } else { + (void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f); + cur_pos += block_len; + } + } + } + } + img_log("Finished reading CopyQM image data\n"); - cqm = 1; - dev->disk_at_once = 1; - fdf = 0; - first_byte = *dev->disk_data; - } else { - dev->disk_at_once = 0; - /* Read the BPB */ - if (ddi) { - img_log("img_load(): File is a DDI image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; - } else - img_log("img_load(): File is a raw image...\n"); - fseek(dev->f, dev->base + 0x0B, SEEK_SET); - (void) !fread(&bpb_bps, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x13, SEEK_SET); - (void) !fread(&bpb_total, 1, 2, dev->f); - fseek(dev->f, dev->base + 0x15, SEEK_SET); - bpb_mid = fgetc(dev->f); - fseek(dev->f, dev->base + 0x18, SEEK_SET); - bpb_sectors = fgetc(dev->f); - fseek(dev->f, dev->base + 0x1A, SEEK_SET); - bpb_sides = fgetc(dev->f); + cqm = 1; + dev->disk_at_once = 1; + fdf = 0; + first_byte = *dev->disk_data; + } else { + dev->disk_at_once = 0; + /* Read the BPB */ + if (ddi) { + img_log("img_load(): File is a DDI image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + } else + img_log("img_load(): File is a raw image...\n"); + fseek(dev->f, dev->base + 0x0B, SEEK_SET); + (void) !fread(&bpb_bps, 1, 2, dev->f); + fseek(dev->f, dev->base + 0x13, SEEK_SET); + (void) !fread(&bpb_total, 1, 2, dev->f); + fseek(dev->f, dev->base + 0x15, SEEK_SET); + bpb_mid = fgetc(dev->f); + fseek(dev->f, dev->base + 0x18, SEEK_SET); + bpb_sectors = fgetc(dev->f); + fseek(dev->f, dev->base + 0x1A, SEEK_SET); + bpb_sides = fgetc(dev->f); - cqm = 0; - } + cqm = 0; + } - fseek(dev->f, -1, SEEK_END); - size = ftell(dev->f) + 1; - if (ddi) - size -= 0x2400; + fseek(dev->f, -1, SEEK_END); + size = ftell(dev->f) + 1; + if (ddi) + size -= 0x2400; jump_if_fdf: - if (!ddi) - dev->base = 0; - fdi = 0; + if (!ddi) + dev->base = 0; + fdi = 0; } - dev->sides = 2; + dev->sides = 2; dev->sector_size = 2; img_log("BPB reports %i sides and %i bytes per sector (%i sectors total)\n", - bpb_sides, bpb_bps, bpb_total); + bpb_sides, bpb_bps, bpb_total); - /* Invalid conditions: */ - guess = (bpb_sides < 1); /* Sides < 1; */ - guess = guess || (bpb_sides > 2); /* Sides > 2; */ - guess = guess || !bps_is_valid(bpb_bps); /* Invalid number of bytes per sector; */ - guess = guess || !first_byte_is_valid(first_byte); /* Invalid first bytes; */ - guess = guess || !is_divisible(bpb_total, bpb_sectors); /* Total sectors not divisible by sectors per track; */ - guess = guess || !is_divisible(bpb_total, bpb_sides); /* Total sectors not divisible by sides. */ + /* Invalid conditions: */ + guess = (bpb_sides < 1); /* Sides < 1; */ + guess = guess || (bpb_sides > 2); /* Sides > 2; */ + guess = guess || !bps_is_valid(bpb_bps); /* Invalid number of bytes per sector; */ + guess = guess || !first_byte_is_valid(first_byte); /* Invalid first bytes; */ + guess = guess || !is_divisible(bpb_total, bpb_sectors); /* Total sectors not divisible by sectors per track; */ + guess = guess || !is_divisible(bpb_total, bpb_sides); /* Total sectors not divisible by sides. */ guess = guess || !fdd_get_check_bpb(drive); guess = guess && !fdi; guess = guess && !cqm; if (guess) { - /* - * The BPB is giving us a wacky number of sides and/or bytes - * per sector, therefore it is most probably not a BPB at all, - * so we have to guess the parameters from file size. - */ - if (size <= (160*1024)) { - dev->sectors = 8; - dev->tracks = 40; - dev->sides = 1; - } else if (size <= (180*1024)) { - dev->sectors = 9; - dev->tracks = 40; - dev->sides = 1; - } else if (size <= (315*1024)) { - dev->sectors = 9; - dev->tracks = 70; - dev->sides = 1; - } else if (size <= (320*1024)) { - dev->sectors = 8; - dev->tracks = 40; - } else if (size <= (320*1024)) { - dev->sectors = 8; - dev->tracks = 40; - } else if (size <= (360*1024)) { /*DD 360K*/ - dev->sectors = 9; - dev->tracks = 40; - } else if (size <= (400*1024)) { /*DEC RX50*/ - dev->sectors = 10; - dev->tracks = 80; - dev->sides = 1; - } else if (size <= (640*1024)) { /*DD 640K*/ - dev->sectors = 8; - dev->tracks = 80; - } else if (size <= (720*1024)) { /*DD 720K*/ - dev->sectors = 9; - dev->tracks = 80; - } else if (size <= (800*1024)) { /*DD*/ - dev->sectors = 10; - dev->tracks = 80; - } else if (size <= (880*1024)) { /*DD*/ - dev->sectors = 11; - dev->tracks = 80; - } else if (size <= (960*1024)) { /*DD*/ - dev->sectors = 12; - dev->tracks = 80; - } else if (size <= (1040*1024)) { /*DD*/ - dev->sectors = 13; - dev->tracks = 80; - } else if (size <= (1120*1024)) { /*DD*/ - dev->sectors = 14; - dev->tracks = 80; - } else if (size <= 1228800) { /*HD 1.2MB*/ - dev->sectors = 15; - dev->tracks = 80; - } else if (size <= 1261568) { /*HD 1.25MB Japanese*/ - dev->sectors = 8; - dev->tracks = 77; - dev->sector_size = 3; - } else if (size <= 1474560) { /*HD 1.44MB*/ - dev->sectors = 18; - dev->tracks = 80; - } else if (size <= 1556480) { /*HD*/ - dev->sectors = 19; - dev->tracks = 80; - } else if (size <= 1638400) { /*HD 1024 sector*/ - dev->sectors = 10; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size <= 1720320) { /*DMF (Windows 95) */ - dev->sectors = 21; - dev->tracks = 80; - } else if (size <= 1741824) { - dev->sectors = 21; - dev->tracks = 81; - } else if (size <= 1763328) { - dev->sectors = 21; - dev->tracks = 82; - } else if (size <= 1802240) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ - dev->sectors = 23; - dev->tracks = 80; - } else if (size <= 2949120) { /*ED*/ - dev->sectors = 36; - dev->tracks = 80; - } else if (size <= 3194880) { /*ED*/ - dev->sectors = 39; - dev->tracks = 80; - } else if (size <= 3276800) { /*ED*/ - dev->sectors = 40; - dev->tracks = 80; - } else if (size <= 3358720) { /*ED, maximum possible size*/ - dev->sectors = 41; - dev->tracks = 80; - } else if (size <= 3440640) { /*ED, maximum possible size*/ - dev->sectors = 42; - dev->tracks = 80; + /* + * The BPB is giving us a wacky number of sides and/or bytes + * per sector, therefore it is most probably not a BPB at all, + * so we have to guess the parameters from file size. + */ + if (size <= (160 * 1024)) { + dev->sectors = 8; + dev->tracks = 40; + dev->sides = 1; + } else if (size <= (180 * 1024)) { + dev->sectors = 9; + dev->tracks = 40; + dev->sides = 1; + } else if (size <= (315 * 1024)) { + dev->sectors = 9; + dev->tracks = 70; + dev->sides = 1; + } else if (size <= (320 * 1024)) { + dev->sectors = 8; + dev->tracks = 40; + } else if (size <= (320 * 1024)) { + dev->sectors = 8; + dev->tracks = 40; + } else if (size <= (360 * 1024)) { /*DD 360K*/ + dev->sectors = 9; + dev->tracks = 40; + } else if (size <= (400 * 1024)) { /*DEC RX50*/ + dev->sectors = 10; + dev->tracks = 80; + dev->sides = 1; + } else if (size <= (640 * 1024)) { /*DD 640K*/ + dev->sectors = 8; + dev->tracks = 80; + } else if (size <= (720 * 1024)) { /*DD 720K*/ + dev->sectors = 9; + dev->tracks = 80; + } else if (size <= (800 * 1024)) { /*DD*/ + dev->sectors = 10; + dev->tracks = 80; + } else if (size <= (880 * 1024)) { /*DD*/ + dev->sectors = 11; + dev->tracks = 80; + } else if (size <= (960 * 1024)) { /*DD*/ + dev->sectors = 12; + dev->tracks = 80; + } else if (size <= (1040 * 1024)) { /*DD*/ + dev->sectors = 13; + dev->tracks = 80; + } else if (size <= (1120 * 1024)) { /*DD*/ + dev->sectors = 14; + dev->tracks = 80; + } else if (size <= 1228800) { /*HD 1.2MB*/ + dev->sectors = 15; + dev->tracks = 80; + } else if (size <= 1261568) { /*HD 1.25MB Japanese*/ + dev->sectors = 8; + dev->tracks = 77; + dev->sector_size = 3; + } else if (size <= 1474560) { /*HD 1.44MB*/ + dev->sectors = 18; + dev->tracks = 80; + } else if (size <= 1556480) { /*HD*/ + dev->sectors = 19; + dev->tracks = 80; + } else if (size <= 1638400) { /*HD 1024 sector*/ + dev->sectors = 10; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size <= 1720320) { /*DMF (Windows 95) */ + dev->sectors = 21; + dev->tracks = 80; + } else if (size <= 1741824) { + dev->sectors = 21; + dev->tracks = 81; + } else if (size <= 1763328) { + dev->sectors = 21; + dev->tracks = 82; + } else if (size <= 1802240) { /*HD 1024 sector*/ + dev->sectors = 22; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size == 1884160) { /*XDF (OS/2 Warp)*/ + dev->sectors = 23; + dev->tracks = 80; + } else if (size <= 2949120) { /*ED*/ + dev->sectors = 36; + dev->tracks = 80; + } else if (size <= 3194880) { /*ED*/ + dev->sectors = 39; + dev->tracks = 80; + } else if (size <= 3276800) { /*ED*/ + dev->sectors = 40; + dev->tracks = 80; + } else if (size <= 3358720) { /*ED, maximum possible size*/ + dev->sectors = 41; + dev->tracks = 80; + } else if (size <= 3440640) { /*ED, maximum possible size*/ + dev->sectors = 42; + dev->tracks = 80; #if 0 } else if (size <= 3440640) { /*HD 1024 sector*/ dev->sectors = 21; dev->tracks = 80; dev->sector_size = 3; #endif - } else if (size <= 3604480) { /*HD 1024 sector*/ - dev->sectors = 22; - dev->tracks = 80; - dev->sector_size = 3; - } else if (size <= 3610624) { /*ED, maximum possible size*/ - dev->sectors = 41; - dev->tracks = 86; - } else if (size <= 3698688) { /*ED, maximum possible size*/ - dev->sectors = 42; - dev->tracks = 86; - } else { - img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; - } + } else if (size <= 3604480) { /*HD 1024 sector*/ + dev->sectors = 22; + dev->tracks = 80; + dev->sector_size = 3; + } else if (size <= 3610624) { /*ED, maximum possible size*/ + dev->sectors = 41; + dev->tracks = 86; + } else if (size <= 3698688) { /*ED, maximum possible size*/ + dev->sectors = 42; + dev->tracks = 86; + } else { + img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; + } - bpb_sides = dev->sides; - bpb_sectors = dev->sectors; - bpb_total = size >> (dev->sector_size + 7); + bpb_sides = dev->sides; + bpb_sectors = dev->sectors; + bpb_total = size >> (dev->sector_size + 7); } else { - /* The BPB readings appear to be valid, so let's set the values. */ - if (fdi) { - /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ - if (fseek(dev->f, 0x1C, SEEK_SET) == -1) - fatal("Japanese FDI: Failed when seeking to 0x1C\n"); - (void) !fread(&(dev->tracks), 1, 4, dev->f); - } else { - if (!cqm && !fdf) { - /* Number of tracks = number of total sectors divided by sides times sectors per track. */ - dev->tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); - } - } + /* The BPB readings appear to be valid, so let's set the values. */ + if (fdi) { + /* The image is a Japanese FDI, therefore we read the number of tracks from the header. */ + if (fseek(dev->f, 0x1C, SEEK_SET) == -1) + fatal("Japanese FDI: Failed when seeking to 0x1C\n"); + (void) !fread(&(dev->tracks), 1, 4, dev->f); + } else { + if (!cqm && !fdf) { + /* Number of tracks = number of total sectors divided by sides times sectors per track. */ + dev->tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); + } + } - /* The rest we just set directly from the BPB. */ - dev->sectors = bpb_sectors; - dev->sides = bpb_sides; + /* The rest we just set directly from the BPB. */ + dev->sectors = bpb_sectors; + dev->sides = bpb_sides; - /* The sector size. */ - dev->sector_size = sector_size_code(bpb_bps); + /* The sector size. */ + dev->sector_size = sector_size_code(bpb_bps); - temp_rate = 0xFF; + temp_rate = 0xFF; } for (i = 0; i < 6; i++) { - if ((dev->sectors <= maximum_sectors[dev->sector_size][i]) || (dev->sectors == xdf_sectors[dev->sector_size][i])) { - bit_rate_300 = bit_rates_300[i]; - temp_rate = rates[i]; - dev->disk_flags = holes[i] << 1; - dev->xdf_type = (dev->sectors == xdf_sectors[dev->sector_size][i]) ? xdf_types[dev->sector_size][i] : 0; - if ((bit_rate_300 == 500.0) && (dev->sectors == 21) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ - dev->dmf = 1; - } else { - if ((bit_rate_300 == 500.0) && (dev->sectors == 22) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { - /* This is marked specially because of the track flag (a RPM slow down is needed). */ - dev->interleave = 2; - } - dev->dmf = 0; - } + if ((dev->sectors <= maximum_sectors[dev->sector_size][i]) || (dev->sectors == xdf_sectors[dev->sector_size][i])) { + bit_rate_300 = bit_rates_300[i]; + temp_rate = rates[i]; + dev->disk_flags = holes[i] << 1; + dev->xdf_type = (dev->sectors == xdf_sectors[dev->sector_size][i]) ? xdf_types[dev->sector_size][i] : 0; + if ((bit_rate_300 == 500.0) && (dev->sectors == 21) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { + /* This is a DMF floppy, set the flag so we know to interleave the sectors. */ + dev->dmf = 1; + } else { + if ((bit_rate_300 == 500.0) && (dev->sectors == 22) && (dev->sector_size == 2) && (dev->tracks >= 80) && (dev->tracks <= 82) && (dev->sides == 2)) { + /* This is marked specially because of the track flag (a RPM slow down is needed). */ + dev->interleave = 2; + } + dev->dmf = 0; + } - img_log("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type); - break; - } + img_log("Image parameters: bit rate 300: %f, temporary rate: %i, hole: %i, DMF: %i, XDF type: %i\n", bit_rate_300, temp_rate, dev->disk_flags >> 1, dev->dmf, dev->xdf_type); + break; + } } if (temp_rate == 0xFF) { - img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + img_log("Image is bigger than can fit on an ED floppy, ejecting...\n"); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; } dev->gap2_size = (temp_rate == 3) ? 41 : 22; if (dev->dmf) - dev->gap3_size = 8; + dev->gap3_size = 8; else { - if (dev->sectors == -1) - dev->gap3_size = 8; - else - dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors]; + if (dev->sectors == -1) + dev->gap3_size = 8; + else + dev->gap3_size = gap3_sizes[temp_rate][dev->sector_size][dev->sectors]; } - if (! dev->gap3_size) { - img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); - fclose(dev->f); - free(dev); - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + if (!dev->gap3_size) { + img_log("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); + fclose(dev->f); + free(dev); + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; } dev->track_width = 0; if (dev->tracks > 43) - dev->track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ + dev->track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ if (dev->sides == 2) - dev->disk_flags |= 8; /* If the has 2 sides, mark it as such. */ + dev->disk_flags |= 8; /* If the has 2 sides, mark it as such. */ if (dev->interleave == 2) { - dev->interleave = 1; - dev->disk_flags |= 0x60; + dev->interleave = 1; + dev->disk_flags |= 0x60; } - dev->track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ - dev->track_flags |= temp_rate & 3; /* Data rate. */ + dev->track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ + dev->track_flags |= temp_rate & 3; /* Data rate. */ if (temp_rate & 4) - dev->track_flags |= 0x20; /* RPM. */ + dev->track_flags |= 0x20; /* RPM. */ dev->is_cqm = cqm; img_log("Disk flags: %i, track flags: %i\n", - dev->disk_flags, dev->track_flags); + dev->disk_flags, dev->track_flags); /* Set up the drive unit. */ img[drive] = dev; /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = write_back; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = poll_write_data; + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = write_back; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = poll_write_data; d86f_handler[drive].format_conditions = format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + d86f_handler[drive].index_hole_pos = null_index_hole_pos; + d86f_handler[drive].get_raw_size = common_get_raw_size; + d86f_handler[drive].check_crc = 1; d86f_set_version(drive, 0x0063); drives[drive].seek = img_seek; @@ -1219,30 +1210,29 @@ jump_if_fdf: d86f_common_handlers(drive); } - void img_close(int drive) { img_t *dev = img[drive]; - if (dev == NULL) return; + if (dev == NULL) + return; d86f_unregister(drive); if (dev->f != NULL) { - fclose(dev->f); - dev->f = NULL; + fclose(dev->f); + dev->f = NULL; } if (dev->disk_data != NULL) - free(dev->disk_data); + free(dev->disk_data); /* Release the memory. */ free(dev); img[drive] = NULL; } - void img_set_fdc(void *fdc) { diff --git a/src/floppy/fdd_td0.c b/src/floppy/fdd_td0.c index 6037bac90..4b478baba 100644 --- a/src/floppy/fdd_td0.c +++ b/src/floppy/fdd_td0.c @@ -43,90 +43,88 @@ #include <86box/fdd_td0.h> #include <86box/fdc.h> - -#define BUFSZ 512 /* new input buffer */ -#define TD0_MAX_BUFSZ (1024UL*1024UL*4UL) +#define BUFSZ 512 /* new input buffer */ +#define TD0_MAX_BUFSZ (1024UL * 1024UL * 4UL) /* LZSS Parameters */ -#define N 4096 /* Size of string buffer */ -#define F 60 /* Size of look-ahead buffer */ -#define THRESHOLD 2 -#define NIL N /* End of tree's node */ +#define N 4096 /* Size of string buffer */ +#define F 60 /* Size of look-ahead buffer */ +#define THRESHOLD 2 +#define NIL N /* End of tree's node */ /* Huffman coding parameters */ -#define N_CHAR (256-THRESHOLD+F) /* code (= 0..N_CHAR-1) */ -#define T (N_CHAR*2-1) /* Size of table */ -#define R (T-1) /* root position */ -#define MAX_FREQ 0x8000 - /* update when cumulative frequency */ - /* reaches to this value */ +#define N_CHAR (256 - THRESHOLD + F) /* code (= 0..N_CHAR-1) */ +#define T (N_CHAR * 2 - 1) /* Size of table */ +#define R (T - 1) /* root position */ +#define MAX_FREQ 0x8000 +/* update when cumulative frequency */ +/* reaches to this value */ typedef struct { - uint16_t r, - bufcnt,bufndx,bufpos, /* string buffer */ - /* the following to allow block reads - from input in next_word() */ - ibufcnt,ibufndx; /* input buffer counters */ - uint8_t inbuf[BUFSZ]; /* input buffer */ + uint16_t r, + bufcnt, bufndx, bufpos, /* string buffer */ + /* the following to allow block reads + from input in next_word() */ + ibufcnt, ibufndx; /* input buffer counters */ + uint8_t inbuf[BUFSZ]; /* input buffer */ } tdlzhuf; typedef struct { - FILE *fdd_file; - off_t fdd_file_offset; + FILE *fdd_file; + off_t fdd_file_offset; - tdlzhuf tdctl; - uint8_t text_buf[N + F - 1]; - uint16_t freq[T + 1]; /* cumulative freq table */ + tdlzhuf tdctl; + uint8_t text_buf[N + F - 1]; + uint16_t freq[T + 1]; /* cumulative freq table */ /* * pointing parent nodes. * area [T..(T + N_CHAR - 1)] are pointers for leaves */ - int16_t prnt[T + N_CHAR]; + int16_t prnt[T + N_CHAR]; /* pointing children nodes (son[], son[] + 1)*/ - int16_t son[T]; + int16_t son[T]; - uint16_t getbuf; - uint8_t getlen; + uint16_t getbuf; + uint8_t getlen; } td0dsk_t; typedef struct { - uint8_t track; - uint8_t head; - uint8_t sector; - uint8_t size; - uint8_t flags; - uint8_t fm; - uint8_t *data; + uint8_t track; + uint8_t head; + uint8_t sector; + uint8_t size; + uint8_t flags; + uint8_t fm; + uint8_t *data; } td0_sector_t; typedef struct { - FILE *f; + FILE *f; - int tracks; - int track_width; - int sides; - uint16_t disk_flags; - uint16_t default_track_flags; - uint16_t side_flags[256][2]; - uint8_t max_sector_size; - uint8_t track_in_file[256][2]; + int tracks; + int track_width; + int sides; + uint16_t disk_flags; + uint16_t default_track_flags; + uint16_t side_flags[256][2]; + uint8_t max_sector_size; + uint8_t track_in_file[256][2]; td0_sector_t sects[256][2][256]; - uint8_t track_spt[256][2]; - uint8_t gap3_len; - uint16_t current_side_flags[2]; - int track; - int current_sector_index[2]; - uint8_t calculated_gap3_lengths[256][2]; - uint8_t xdf_ordered_pos[256][2]; - uint8_t interleave_ordered_pos[256][2]; + uint8_t track_spt[256][2]; + uint8_t gap3_len; + uint16_t current_side_flags[2]; + int track; + int current_sector_index[2]; + uint8_t calculated_gap3_lengths[256][2]; + uint8_t xdf_ordered_pos[256][2]; + uint8_t interleave_ordered_pos[256][2]; - uint8_t *imagebuf; - uint8_t *processed_buf; + uint8_t *imagebuf; + uint8_t *processed_buf; } td0_t; - /* * Tables for encoding/decoding upper 6 bits of * sliding dictionary pointer @@ -201,8 +199,7 @@ static const uint8_t d_len[256] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; - -static td0_t *td0[FDD_NUM]; +static td0_t *td0[FDD_NUM]; #ifdef ENABLE_TD0_LOG int td0_do_log = ENABLE_TD0_LOG; @@ -210,47 +207,43 @@ int td0_do_log = ENABLE_TD0_LOG; static void td0_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (td0_do_log) - { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (td0_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define td0_log(fmt, ...) +# define td0_log(fmt, ...) #endif - static void fdd_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) { td0_t *dev = td0[drive]; if (fseek(dev->f, offset, SEEK_SET) == -1) - fatal("fdd_image_read(): Error seeking to the beginning of the file\n"); + fatal("fdd_image_read(): Error seeking to the beginning of the file\n"); if (fread(buffer, 1, len, dev->f) != len) - fatal("fdd_image_read(): Error reading data\n"); + fatal("fdd_image_read(): Error reading data\n"); } - static int dsk_identify(int drive) { char header[2]; fdd_image_read(drive, header, 0, 2); - if (header[0]=='T' && header[1]=='D') - return(1); - else if (header[0]=='t' && header[1]=='d') - return(1); + if (header[0] == 'T' && header[1] == 'D') + return (1); + else if (header[0] == 't' && header[1] == 'd') + return (1); - return(0); + return (0); } - static int state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) { @@ -259,36 +252,34 @@ state_data_read(td0dsk_t *state, uint8_t *buf, uint16_t size) fseek(state->fdd_file, 0, SEEK_END); image_size = ftell(state->fdd_file); if (size > image_size - state->fdd_file_offset) - size = (image_size - state->fdd_file_offset) & 0xffff; + size = (image_size - state->fdd_file_offset) & 0xffff; if (fseek(state->fdd_file, state->fdd_file_offset, SEEK_SET) == -1) - fatal("TD0: Failed to seek in state_data_read()\n"); + fatal("TD0: Failed to seek in state_data_read()\n"); if (fread(buf, 1, size, state->fdd_file) != size) - fatal("TD0: Error reading data in state_data_read()\n"); + fatal("TD0: Error reading data in state_data_read()\n"); state->fdd_file_offset += size; - return(size); + return (size); } - static int state_next_word(td0dsk_t *state) { if (state->tdctl.ibufndx >= state->tdctl.ibufcnt) { - state->tdctl.ibufndx = 0; - state->tdctl.ibufcnt = state_data_read(state, state->tdctl.inbuf,BUFSZ); - if (state->tdctl.ibufcnt == 0) - return(-1); + state->tdctl.ibufndx = 0; + state->tdctl.ibufcnt = state_data_read(state, state->tdctl.inbuf, BUFSZ); + if (state->tdctl.ibufcnt == 0) + return (-1); } while (state->getlen <= 8) { /* typically reads a word at a time */ - state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); - state->getlen += 8; + state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); + state->getlen += 8; } - return(0); + return (0); } - /* get one bit */ static int state_GetBit(td0dsk_t *state) @@ -296,18 +287,17 @@ state_GetBit(td0dsk_t *state) int16_t i; if (state_next_word(state) < 0) - return(-1); + return (-1); i = state->getbuf; state->getbuf <<= 1; state->getlen--; if (i < 0) - return(1); + return (1); - return(0); + return (0); } - /* get a byte */ static int state_GetByte(td0dsk_t *state) @@ -315,17 +305,16 @@ state_GetByte(td0dsk_t *state) uint16_t i; if (state_next_word(state) != 0) - return(-1); + return (-1); i = state->getbuf; state->getbuf <<= 8; state->getlen -= 8; i = i >> 8; - return((int) i); + return ((int) i); } - /* initialize freq tree */ static void state_StartHuff(td0dsk_t *state) @@ -333,65 +322,65 @@ state_StartHuff(td0dsk_t *state) int i, j; for (i = 0; i < N_CHAR; i++) { - state->freq[i] = 1; - state->son[i] = i + T; - state->prnt[i + T] = i; + state->freq[i] = 1; + state->son[i] = i + T; + state->prnt[i + T] = i; } - i = 0; j = N_CHAR; + i = 0; + j = N_CHAR; while (j <= R) { - state->freq[j] = state->freq[i] + state->freq[i + 1]; - state->son[j] = i; - state->prnt[i] = state->prnt[i + 1] = j; - i += 2; j++; + state->freq[j] = state->freq[i] + state->freq[i + 1]; + state->son[j] = i; + state->prnt[i] = state->prnt[i + 1] = j; + i += 2; + j++; } state->freq[T] = 0xffff; state->prnt[R] = 0; } - /* reconstruct freq tree */ static void state_reconst(td0dsk_t *state) { - int16_t i, j, k; + int16_t i, j, k; uint16_t f, l; /* halven cumulative freq for leaf nodes */ j = 0; for (i = 0; i < T; i++) { - if (state->son[i] >= T) { - state->freq[j] = (state->freq[i] + 1) / 2; - state->son[j] = state->son[i]; - j++; - } + if (state->son[i] >= T) { + state->freq[j] = (state->freq[i] + 1) / 2; + state->son[j] = state->son[i]; + j++; + } } /* make a tree : first, connect children nodes */ for (i = 0, j = N_CHAR; j < T; i += 2, j++) { - k = i + 1; - f = state->freq[j] = state->freq[i] + state->freq[k]; - for (k = j - 1; f < state->freq[k]; k--) {}; - k++; - l = (j - k) * 2; + k = i + 1; + f = state->freq[j] = state->freq[i] + state->freq[k]; + for (k = j - 1; f < state->freq[k]; k--) { }; + k++; + l = (j - k) * 2; - /* These *HAVE* to be memmove's as destination and source - can overlap, which memcpy can't handle. */ - memmove(&state->freq[k + 1], &state->freq[k], l); - state->freq[k] = f; - memmove(&state->son[k + 1], &state->son[k], l); - state->son[k] = i; + /* These *HAVE* to be memmove's as destination and source + can overlap, which memcpy can't handle. */ + memmove(&state->freq[k + 1], &state->freq[k], l); + state->freq[k] = f; + memmove(&state->son[k + 1], &state->son[k], l); + state->son[k] = i; } /* connect parent nodes */ for (i = 0; i < T; i++) { - if ((k = state->son[i]) >= T) - state->prnt[k] = i; - else - state->prnt[k] = state->prnt[k + 1] = i; + if ((k = state->son[i]) >= T) + state->prnt[k] = i; + else + state->prnt[k] = state->prnt[k + 1] = i; } } - /* update freq tree */ static void state_update(td0dsk_t *state, int c) @@ -399,42 +388,43 @@ state_update(td0dsk_t *state, int c) int i, j, k, l; if (state->freq[R] == MAX_FREQ) - state_reconst(state); + state_reconst(state); c = state->prnt[c + T]; /* do it until reaching the root */ do { - k = ++state->freq[c]; + k = ++state->freq[c]; - /* swap nodes to keep the tree freq-ordered */ - if (k > state->freq[l = c + 1]) { - while (k > state->freq[++l]) {}; - l--; - state->freq[c] = state->freq[l]; - state->freq[l] = k; + /* swap nodes to keep the tree freq-ordered */ + if (k > state->freq[l = c + 1]) { + while (k > state->freq[++l]) { }; + l--; + state->freq[c] = state->freq[l]; + state->freq[l] = k; - i = state->son[c]; - state->prnt[i] = l; - if (i < T) state->prnt[i + 1] = l; + i = state->son[c]; + state->prnt[i] = l; + if (i < T) + state->prnt[i + 1] = l; - j = state->son[l]; - state->son[l] = i; + j = state->son[l]; + state->son[l] = i; - state->prnt[j] = c; - if (j < T) state->prnt[j + 1] = c; - state->son[c] = j; + state->prnt[j] = c; + if (j < T) + state->prnt[j + 1] = c; + state->son[c] = j; - c = l; - } + c = l; + } } while ((c = state->prnt[c]) != 0); } - static int16_t state_DecodeChar(td0dsk_t *state) { - int ret; + int ret; uint16_t c; c = state->son[R]; @@ -445,201 +435,196 @@ state_DecodeChar(td0dsk_t *state) * else choose #(son[]+1) (input bit == 1) */ while (c < T) { - if ((ret = state_GetBit(state)) < 0) - return(-1); - c += (unsigned) ret; - c = state->son[c]; + if ((ret = state_GetBit(state)) < 0) + return (-1); + c += (unsigned) ret; + c = state->son[c]; } c -= T; state_update(state, c); - return(c); + return (c); } - static int16_t state_DecodePosition(td0dsk_t *state) { - int16_t bit; + int16_t bit; uint16_t i, j, c; /* decode upper 6 bits from given table */ if ((bit = state_GetByte(state)) < 0) - return(-1); + return (-1); i = (uint16_t) bit; - c = (uint16_t)d_code[i] << 6; + c = (uint16_t) d_code[i] << 6; j = d_len[i]; /* input lower 6 bits directly */ j -= 2; while (j--) { - if ((bit = state_GetBit(state)) < 0) - return(-1); - i = (i << 1) + bit; + if ((bit = state_GetBit(state)) < 0) + return (-1); + i = (i << 1) + bit; } - return(c | (i & 0x3f)); + return (c | (i & 0x3f)); } - /* DeCompression - split out initialization code to init_Decode() */ static void state_init_Decode(td0dsk_t *state) { int i; - state->getbuf = 0; - state->getlen = 0; - state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; /* input buffer is empty */ - state->tdctl.bufcnt = 0; + state->getbuf = 0; + state->getlen = 0; + state->tdctl.ibufcnt = state->tdctl.ibufndx = 0; /* input buffer is empty */ + state->tdctl.bufcnt = 0; state_StartHuff(state); for (i = 0; i < N - F; i++) - state->text_buf[i] = ' '; + state->text_buf[i] = ' '; state->tdctl.r = N - F; } - /* Decoding/Uncompressing */ static int state_Decode(td0dsk_t *state, uint8_t *buf, int len) { int16_t c, pos; - int count; /* was an unsigned long, seems unnecessary */ + int count; /* was an unsigned long, seems unnecessary */ - for (count = 0; count < len; ) { - if (state->tdctl.bufcnt == 0) { - if ((c = state_DecodeChar(state)) < 0) - return(count); /* fatal error */ - if (c < 256) { - *(buf++) = c & 0xff; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } else { - if ((pos = state_DecodePosition(state)) < 0) - return(count); /* fatal error */ - state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); - state->tdctl.bufcnt = c - 255 + THRESHOLD; - state->tdctl.bufndx = 0; - } - } else { - /* still chars from last string */ - while (state->tdctl.bufndx < state->tdctl.bufcnt && count < len) { - c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; - *(buf++) = c & 0xff; - state->tdctl.bufndx++; - state->text_buf[state->tdctl.r++] = c & 0xff; - state->tdctl.r &= (N - 1); - count++; - } + for (count = 0; count < len;) { + if (state->tdctl.bufcnt == 0) { + if ((c = state_DecodeChar(state)) < 0) + return (count); /* fatal error */ + if (c < 256) { + *(buf++) = c & 0xff; + state->text_buf[state->tdctl.r++] = c & 0xff; + state->tdctl.r &= (N - 1); + count++; + } else { + if ((pos = state_DecodePosition(state)) < 0) + return (count); /* fatal error */ + state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); + state->tdctl.bufcnt = c - 255 + THRESHOLD; + state->tdctl.bufndx = 0; + } + } else { + /* still chars from last string */ + while (state->tdctl.bufndx < state->tdctl.bufcnt && count < len) { + c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; + *(buf++) = c & 0xff; + state->tdctl.bufndx++; + state->text_buf[state->tdctl.r++] = c & 0xff; + state->tdctl.r &= (N - 1); + count++; + } - /* reset bufcnt after copy string from text_buf[] */ - if (state->tdctl.bufndx >= state->tdctl.bufcnt) - state->tdctl.bufndx = state->tdctl.bufcnt = 0; - } + /* reset bufcnt after copy string from text_buf[] */ + if (state->tdctl.bufndx >= state->tdctl.bufcnt) + state->tdctl.bufndx = state->tdctl.bufcnt = 0; + } } - return(count); /* count == len, success */ + return (count); /* count == len, success */ } - static uint32_t get_raw_tsize(int side_flags, int slower_rpm) { uint32_t size; - switch(side_flags & 0x27) { - case 0x22: - size = slower_rpm ? 5314 : 5208; - break; + switch (side_flags & 0x27) { + case 0x22: + size = slower_rpm ? 5314 : 5208; + break; - default: - case 0x02: - case 0x21: - size = slower_rpm ? 6375 : 6250; - break; + default: + case 0x02: + case 0x21: + size = slower_rpm ? 6375 : 6250; + break; - case 0x01: - size = slower_rpm ? 7650 : 7500; - break; + case 0x01: + size = slower_rpm ? 7650 : 7500; + break; - case 0x20: - size = slower_rpm ? 10629 : 10416; - break; + case 0x20: + size = slower_rpm ? 10629 : 10416; + break; - case 0x00: - size = slower_rpm ? 12750 : 12500; - break; + case 0x00: + size = slower_rpm ? 12750 : 12500; + break; - case 0x23: - size = slower_rpm ? 21258 : 20833; - break; + case 0x23: + size = slower_rpm ? 21258 : 20833; + break; - case 0x03: - size = slower_rpm ? 25500 : 25000; - break; + case 0x03: + size = slower_rpm ? 25500 : 25000; + break; - case 0x25: - size = slower_rpm ? 42517 : 41666; - break; + case 0x25: + size = slower_rpm ? 42517 : 41666; + break; - case 0x05: - size = slower_rpm ? 51000 : 50000; - break; + case 0x05: + size = slower_rpm ? 51000 : 50000; + break; } - return(size); + return (size); } - static int td0_initialize(int drive) { - td0_t *dev = td0[drive]; - uint8_t header[12]; - int fm, head, track; - int track_count = 0; - int head_count = 0; - int track_spt, track_spt_adjusted; - int offset = 0; - int density = 0; - int temp_rate = 0; + td0_t *dev = td0[drive]; + uint8_t header[12]; + int fm, head, track; + int track_count = 0; + int head_count = 0; + int track_spt, track_spt_adjusted; + int offset = 0; + int density = 0; + int temp_rate = 0; uint32_t file_size; uint16_t len, rep; td0dsk_t disk_decode; uint8_t *hs; uint16_t size; - uint8_t *dbuf = dev->processed_buf; - uint32_t total_size = 0; - uint32_t id_field = 0; - uint32_t pre_sector = 0; - int32_t track_size = 0; - int32_t raw_tsize = 0; + uint8_t *dbuf = dev->processed_buf; + uint32_t total_size = 0; + uint32_t id_field = 0; + uint32_t pre_sector = 0; + int32_t track_size = 0; + int32_t raw_tsize = 0; uint32_t minimum_gap3 = 0; uint32_t minimum_gap4 = 0; - int i, j, k; - int size_diff, gap_sum; + int i, j, k; + int size_diff, gap_sum; if (dev->f == NULL) { - td0_log("TD0: Attempted to initialize without loading a file first\n"); - return(0); + td0_log("TD0: Attempted to initialize without loading a file first\n"); + return (0); } fseek(dev->f, 0, SEEK_END); file_size = ftell(dev->f); if (file_size < 12) { - td0_log("TD0: File is too small to even contain the header\n"); - return(0); + td0_log("TD0: File is too small to even contain the header\n"); + return (0); } if (file_size > TD0_MAX_BUFSZ) { - td0_log("TD0: File exceeds the maximum size\n"); - return(0); + td0_log("TD0: File exceeds the maximum size\n"); + return (0); } fseek(dev->f, 0, SEEK_SET); @@ -647,34 +632,34 @@ td0_initialize(int drive) head_count = header[9]; if (header[0] == 't') { - td0_log("TD0: File is compressed\n"); - disk_decode.fdd_file = dev->f; - state_init_Decode(&disk_decode); - disk_decode.fdd_file_offset = 12; - state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); + td0_log("TD0: File is compressed\n"); + disk_decode.fdd_file = dev->f; + state_init_Decode(&disk_decode); + disk_decode.fdd_file_offset = 12; + state_Decode(&disk_decode, dev->imagebuf, TD0_MAX_BUFSZ); } else { - td0_log("TD0: File is uncompressed\n"); - if (fseek(dev->f, 12, SEEK_SET) == -1) - fatal("td0_initialize(): Error seeking to offet 12\n"); - if (fread(dev->imagebuf, 1, file_size - 12, dev->f) != (file_size - 12)) - fatal("td0_initialize(): Error reading image buffer\n"); + td0_log("TD0: File is uncompressed\n"); + if (fseek(dev->f, 12, SEEK_SET) == -1) + fatal("td0_initialize(): Error seeking to offet 12\n"); + if (fread(dev->imagebuf, 1, file_size - 12, dev->f) != (file_size - 12)) + fatal("td0_initialize(): Error reading image buffer\n"); } if (header[7] & 0x80) - offset = 10 + dev->imagebuf[2] + (dev->imagebuf[3] << 8); + offset = 10 + dev->imagebuf[2] + (dev->imagebuf[3] << 8); track_spt = dev->imagebuf[offset]; if (track_spt == 255) { - /* Empty file? */ - td0_log("TD0: File has no tracks\n"); - return(0); + /* Empty file? */ + td0_log("TD0: File has no tracks\n"); + return (0); } density = (header[5] >> 1) & 3; if (density == 3) { - td0_log("TD0: Unknown density\n"); - return(0); + td0_log("TD0: Unknown density\n"); + return (0); } /* @@ -683,30 +668,30 @@ td0_initialize(int drive) * from the CMOS. */ switch (header[6]) { - case 0: /* 5.25" 360k in 1.2M drive: 360 rpm - CMOS Drive type: None, value probably - reused by Teledisk */ - case 2: /* 5.25" 1.2M 360 rpm */ - case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ - dev->default_track_flags = (density == 1) ? 0x20 : 0x21; - dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ - break; + case 0: /* 5.25" 360k in 1.2M drive: 360 rpm + CMOS Drive type: None, value probably + reused by Teledisk */ + case 2: /* 5.25" 1.2M 360 rpm */ + case 5: /* 8"/5.25"/3.5" 1.25M 360 rpm */ + dev->default_track_flags = (density == 1) ? 0x20 : 0x21; + dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ + break; - case 1: /* 5.25" 360k: 300 rpm */ - case 3: /* 3.5" 720k: 300 rpm */ - dev->default_track_flags = 0x02; - dev->max_sector_size = 5; /* 4096 bytes. */ - break; + case 1: /* 5.25" 360k: 300 rpm */ + case 3: /* 3.5" 720k: 300 rpm */ + dev->default_track_flags = 0x02; + dev->max_sector_size = 5; /* 4096 bytes. */ + break; - case 4: /* 3.5" 1.44M: 300 rpm */ - dev->default_track_flags = (density == 1) ? 0x00 : 0x02; - dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ - break; + case 4: /* 3.5" 1.44M: 300 rpm */ + dev->default_track_flags = (density == 1) ? 0x00 : 0x02; + dev->max_sector_size = (density == 1) ? 6 : 5; /* 8192 or 4096 bytes. */ + break; - case 6: /* 3.5" 2.88M: 300 rpm */ - dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); - dev->max_sector_size = (density == 1) ? 6 : ((density == 2) ? 7 : 5); /* 16384, 8192, or 4096 bytes. */ - break; + case 6: /* 3.5" 2.88M: 300 rpm */ + dev->default_track_flags = (density == 1) ? 0x00 : ((density == 2) ? 0x03 : 0x02); + dev->max_sector_size = (density == 1) ? 6 : ((density == 2) ? 7 : 5); /* 16384, 8192, or 4096 bytes. */ + break; } dev->disk_flags = header[5] & 0x06; @@ -714,161 +699,161 @@ td0_initialize(int drive) dev->track_width = (header[7] & 1) ^ 1; for (i = 0; i < 256; i++) { - memset(dev->side_flags[i], 0, 4); - memset(dev->track_in_file[i], 0, 2); - memset(dev->calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); + memset(dev->side_flags[i], 0, 4); + memset(dev->track_in_file[i], 0, 2); + memset(dev->calculated_gap3_lengths[i], 0, 2); + for (j = 0; j < 2; j++) + memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); } while (track_spt != 255) { - track_spt_adjusted = track_spt; + track_spt_adjusted = track_spt; - track = dev->imagebuf[offset + 1]; - head = dev->imagebuf[offset + 2] & 1; - fm = (header[5] & 0x80) || (dev->imagebuf[offset + 2] & 0x80); /* ? */ - dev->side_flags[track][head] = dev->default_track_flags | (fm ? 0 : 8); - dev->track_in_file[track][head] = 1; - offset += 4; - track_size = fm ? 73 : 146; - if (density == 2) - id_field = fm ? 54 : 63; - else - id_field = fm ? 35 : 44; - pre_sector = id_field + (fm ? 7 : 16); + track = dev->imagebuf[offset + 1]; + head = dev->imagebuf[offset + 2] & 1; + fm = (header[5] & 0x80) || (dev->imagebuf[offset + 2] & 0x80); /* ? */ + dev->side_flags[track][head] = dev->default_track_flags | (fm ? 0 : 8); + dev->track_in_file[track][head] = 1; + offset += 4; + track_size = fm ? 73 : 146; + if (density == 2) + id_field = fm ? 54 : 63; + else + id_field = fm ? 35 : 44; + pre_sector = id_field + (fm ? 7 : 16); - for (i = 0; i < track_spt; i++) { - hs = &dev->imagebuf[offset]; - offset += 6; + for (i = 0; i < track_spt; i++) { + hs = &dev->imagebuf[offset]; + offset += 6; - dev->sects[track][head][i].track = hs[0]; - dev->sects[track][head][i].head = hs[1]; - dev->sects[track][head][i].sector = hs[2]; - dev->sects[track][head][i].size = hs[3]; - dev->sects[track][head][i].flags = hs[4]; - dev->sects[track][head][i].fm = !!fm; - dev->sects[track][head][i].data = dbuf; + dev->sects[track][head][i].track = hs[0]; + dev->sects[track][head][i].head = hs[1]; + dev->sects[track][head][i].sector = hs[2]; + dev->sects[track][head][i].size = hs[3]; + dev->sects[track][head][i].flags = hs[4]; + dev->sects[track][head][i].fm = !!fm; + dev->sects[track][head][i].data = dbuf; - size = 128 << hs[3]; - if ((total_size + size) >= TD0_MAX_BUFSZ) { - td0_log("TD0: Processed buffer overflow\n"); - return(0); - } + size = 128 << hs[3]; + if ((total_size + size) >= TD0_MAX_BUFSZ) { + td0_log("TD0: Processed buffer overflow\n"); + return (0); + } - if (hs[4] & 0x30) - memset(dbuf, (hs[4] & 0x10) ? 0xf6 : 0x00, size); - else { - offset += 3; - switch (hs[8]) { - default: - td0_log("TD0: Image uses an unsupported sector data encoding: %i\n", hs[8]); - return(0); + if (hs[4] & 0x30) + memset(dbuf, (hs[4] & 0x10) ? 0xf6 : 0x00, size); + else { + offset += 3; + switch (hs[8]) { + default: + td0_log("TD0: Image uses an unsupported sector data encoding: %i\n", hs[8]); + return (0); - case 0: - memcpy(dbuf, &dev->imagebuf[offset], size); - offset += size; - break; + case 0: + memcpy(dbuf, &dev->imagebuf[offset], size); + offset += size; + break; - case 1: - offset += 4; - k = (hs[9] + (hs[10] << 8)) * 2; - k = (k <= size) ? k : size; - for(j = 0; j < k; j += 2) { - dbuf[j] = hs[11]; - dbuf[j + 1] = hs[12]; - } - if (k < size) - memset(&(dbuf[k]), 0, size - k); - break; + case 1: + offset += 4; + k = (hs[9] + (hs[10] << 8)) * 2; + k = (k <= size) ? k : size; + for (j = 0; j < k; j += 2) { + dbuf[j] = hs[11]; + dbuf[j + 1] = hs[12]; + } + if (k < size) + memset(&(dbuf[k]), 0, size - k); + break; - case 2: - k = 0; - while (k < size) { - len = dev->imagebuf[offset]; - rep = dev->imagebuf[offset + 1]; - offset += 2; - if (! len) { - memcpy(&(dbuf[k]), &dev->imagebuf[offset], rep); - offset += rep; - k += rep; - } else { - len = (1 << len); - rep = len * rep; - rep = ((rep + k) <= size) ? rep : (size - k); - for(j = 0; j < rep; j += len) - memcpy(&(dbuf[j + k]), &dev->imagebuf[offset], len); - k += rep; - offset += len; - } - } - break; - } - } + case 2: + k = 0; + while (k < size) { + len = dev->imagebuf[offset]; + rep = dev->imagebuf[offset + 1]; + offset += 2; + if (!len) { + memcpy(&(dbuf[k]), &dev->imagebuf[offset], rep); + offset += rep; + k += rep; + } else { + len = (1 << len); + rep = len * rep; + rep = ((rep + k) <= size) ? rep : (size - k); + for (j = 0; j < rep; j += len) + memcpy(&(dbuf[j + k]), &dev->imagebuf[offset], len); + k += rep; + offset += len; + } + } + break; + } + } - dbuf += size; - total_size += size; + dbuf += size; + total_size += size; - if (hs[4] & 0x20) { - track_size += id_field; - track_spt_adjusted--; - } else if (hs[4] & 0x40) - track_size += (pre_sector - id_field + 3); - else { - if ((hs[4] & 0x02) || (hs[3] > (dev->max_sector_size - fm))) - track_size += (pre_sector + 3); - else - track_size += (pre_sector + size + 2); - } - } + if (hs[4] & 0x20) { + track_size += id_field; + track_spt_adjusted--; + } else if (hs[4] & 0x40) + track_size += (pre_sector - id_field + 3); + else { + if ((hs[4] & 0x02) || (hs[3] > (dev->max_sector_size - fm))) + track_size += (pre_sector + 3); + else + track_size += (pre_sector + size + 2); + } + } - if (track > track_count) - track_count = track; + if (track > track_count) + track_count = track; - if (track_spt != 255) { - dev->track_spt[track][head] = track_spt; + if (track_spt != 255) { + dev->track_spt[track][head] = track_spt; - if ((dev->track_spt[track][head] == 8) && (dev->sects[track][head][0].size == 3)) - dev->side_flags[track][head] = (dev->side_flags[track][head] & ~0x67) | 0x20; + if ((dev->track_spt[track][head] == 8) && (dev->sects[track][head][0].size == 3)) + dev->side_flags[track][head] = (dev->side_flags[track][head] & ~0x67) | 0x20; - raw_tsize = get_raw_tsize(dev->side_flags[track][head], 0); - minimum_gap3 = 12 * track_spt_adjusted; - size_diff = raw_tsize - track_size; - gap_sum = minimum_gap3 + minimum_gap4; - if (size_diff < gap_sum) { - /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ - raw_tsize = get_raw_tsize(dev->side_flags[track][head], 1); - /* Set disk flags so that rotation speed is 2% slower. */ - dev->disk_flags |= (3 << 5); - size_diff = raw_tsize - track_size; - if ((size_diff < gap_sum) && !fdd_get_turbo(drive)) { - /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ - td0_log("TD0: Unable to fit the %i sectors into drive %i, track %i, side %i\n", track_spt_adjusted, drive, track, head); - return 0; - } - } - dev->calculated_gap3_lengths[track][head] = (size_diff - minimum_gap4) / track_spt_adjusted; + raw_tsize = get_raw_tsize(dev->side_flags[track][head], 0); + minimum_gap3 = 12 * track_spt_adjusted; + size_diff = raw_tsize - track_size; + gap_sum = minimum_gap3 + minimum_gap4; + if (size_diff < gap_sum) { + /* If we can't fit the sectors with a reasonable minimum gap at perfect RPM, let's try 2% slower. */ + raw_tsize = get_raw_tsize(dev->side_flags[track][head], 1); + /* Set disk flags so that rotation speed is 2% slower. */ + dev->disk_flags |= (3 << 5); + size_diff = raw_tsize - track_size; + if ((size_diff < gap_sum) && !fdd_get_turbo(drive)) { + /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ + td0_log("TD0: Unable to fit the %i sectors into drive %i, track %i, side %i\n", track_spt_adjusted, drive, track, head); + return 0; + } + } + dev->calculated_gap3_lengths[track][head] = (size_diff - minimum_gap4) / track_spt_adjusted; - track_spt = dev->imagebuf[offset]; - } + track_spt = dev->imagebuf[offset]; + } } if ((dev->disk_flags & 0x60) == 0x60) - td0_log("TD0: Disk will rotate 2% below perfect RPM\n"); + td0_log("TD0: Disk will rotate 2% below perfect RPM\n"); dev->tracks = track_count + 1; temp_rate = dev->default_track_flags & 7; if ((dev->default_track_flags & 0x27) == 0x20) - temp_rate = 4; + temp_rate = 4; dev->gap3_len = gap3_sizes[temp_rate][dev->sects[0][0][0].size][dev->track_spt[0][0]]; - if (! dev->gap3_len) - dev->gap3_len = dev->calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ + if (!dev->gap3_len) + dev->gap3_len = dev->calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ if (head_count == 2) - dev->disk_flags |= 8; /* 2 sides */ + dev->disk_flags |= 8; /* 2 sides */ if (dev->tracks <= 43) - dev->track_width &= ~1; + dev->track_width &= ~1; dev->sides = head_count; @@ -877,198 +862,192 @@ td0_initialize(int drive) td0_log("TD0: File loaded: %i tracks, %i sides, disk flags: %02X, side flags: %02X, %02X, GAP3 length: %02X\n", dev->tracks, dev->sides, dev->disk_flags, dev->current_side_flags[0], dev->current_side_flags[1], dev->gap3_len); - return(1); + return (1); } - static uint16_t disk_flags(int drive) { td0_t *dev = td0[drive]; - return(dev->disk_flags); + return (dev->disk_flags); } - static uint16_t side_flags(int drive) { - td0_t *dev = td0[drive]; - int side = 0; + td0_t *dev = td0[drive]; + int side = 0; uint16_t sflags = 0; - side = fdd_get_head(drive); + side = fdd_get_head(drive); sflags = dev->current_side_flags[side]; - return(sflags); + return (sflags); } - static void set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_t n) { td0_t *dev = td0[drive]; - int i = 0, cyl = c; + int i = 0, cyl = c; dev->current_sector_index[side] = 0; - if (cyl != dev->track) return; + if (cyl != dev->track) + return; for (i = 0; i < dev->track_spt[cyl][side]; i++) { - if ((dev->sects[cyl][side][i].track == c) && - (dev->sects[cyl][side][i].head == h) && - (dev->sects[cyl][side][i].sector == r) && - (dev->sects[cyl][side][i].size == n)) { - dev->current_sector_index[side] = i; - } + if ((dev->sects[cyl][side][i].track == c) && (dev->sects[cyl][side][i].head == h) && (dev->sects[cyl][side][i].sector == r) && (dev->sects[cyl][side][i].size == n)) { + dev->current_sector_index[side] = i; + } } } - static uint8_t poll_read_data(int drive, int side, uint16_t pos) { td0_t *dev = td0[drive]; - return(dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); + return (dev->sects[dev->track][side][dev->current_sector_index[side]].data[pos]); } - static int track_is_xdf(int drive, int side, int track) { - td0_t *dev = td0[drive]; + td0_t *dev = td0[drive]; uint8_t id[4] = { 0, 0, 0, 0 }; - int i, effective_sectors, xdf_sectors; - int high_sectors, low_sectors; - int max_high_id, expected_high_count, expected_low_count; + int i, effective_sectors, xdf_sectors; + int high_sectors, low_sectors; + int max_high_id, expected_high_count, expected_low_count; effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; memset(dev->xdf_ordered_pos[side], 0, 256); - if (! track) { - if ((dev->track_spt[track][side] == 16) || (dev->track_spt[track][side] == 19)) { - if (! side) { - max_high_id = (dev->track_spt[track][side] == 19) ? 0x8B : 0x88; - expected_high_count = (dev->track_spt[track][side] == 19) ? 0x0B : 0x08; - expected_low_count = 8; - } else { - max_high_id = (dev->track_spt[track][side] == 19) ? 0x93 : 0x90; - expected_high_count = (dev->track_spt[track][side] == 19) ? 0x13 : 0x10; - expected_low_count = 0; - } + if (!track) { + if ((dev->track_spt[track][side] == 16) || (dev->track_spt[track][side] == 19)) { + if (!side) { + max_high_id = (dev->track_spt[track][side] == 19) ? 0x8B : 0x88; + expected_high_count = (dev->track_spt[track][side] == 19) ? 0x0B : 0x08; + expected_low_count = 8; + } else { + max_high_id = (dev->track_spt[track][side] == 19) ? 0x93 : 0x90; + expected_high_count = (dev->track_spt[track][side] == 19) ? 0x13 : 0x10; + expected_low_count = 0; + } - for (i = 0; i < dev->track_spt[track][side]; i++) { - id[0] = dev->sects[track][side][i].track; - id[1] = dev->sects[track][side][i].head; - id[2] = dev->sects[track][side][i].sector; - id[3] = dev->sects[track][side][i].size; - if (!(id[0]) && (id[1] == side) && (id[3] == 2)) { - if ((id[2] >= 0x81) && (id[2] <= max_high_id)) { - high_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } + for (i = 0; i < dev->track_spt[track][side]; i++) { + id[0] = dev->sects[track][side][i].track; + id[1] = dev->sects[track][side][i].head; + id[2] = dev->sects[track][side][i].sector; + id[3] = dev->sects[track][side][i].size; + if (!(id[0]) && (id[1] == side) && (id[3] == 2)) { + if ((id[2] >= 0x81) && (id[2] <= max_high_id)) { + high_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; + } - if ((id[2] >= 0x01) && (id[2] <= 0x08)) { - low_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - } - } + if ((id[2] >= 0x01) && (id[2] <= 0x08)) { + low_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; + } + } + } - if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { - dev->current_side_flags[side] = (dev->track_spt[track][side] == 19) ? 0x08 : 0x28; - return((dev->track_spt[track][side] == 19) ? 2 : 1); - } - } + if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { + dev->current_side_flags[side] = (dev->track_spt[track][side] == 19) ? 0x08 : 0x28; + return ((dev->track_spt[track][side] == 19) ? 2 : 1); + } + } } else { - for (i = 0; i < dev->track_spt[track][side]; i++) { - id[0] = dev->sects[track][side][i].track; - id[1] = dev->sects[track][side][i].head; - id[2] = dev->sects[track][side][i].sector; - id[3] = dev->sects[track][side][i].size; - effective_sectors++; - if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) { - effective_sectors--; - } - if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) { - xdf_sectors++; - dev->xdf_ordered_pos[id[2]][side] = i; - } - } + for (i = 0; i < dev->track_spt[track][side]; i++) { + id[0] = dev->sects[track][side][i].track; + id[1] = dev->sects[track][side][i].head; + id[2] = dev->sects[track][side][i].sector; + id[3] = dev->sects[track][side][i].size; + effective_sectors++; + if ((id[0] == track) && (id[1] == side) && !(id[2]) && !(id[3])) { + effective_sectors--; + } + if ((id[0] == track) && (id[1] == side) && (id[2] == (id[3] | 0x80))) { + xdf_sectors++; + dev->xdf_ordered_pos[id[2]][side] = i; + } + } - if ((effective_sectors == 3) && (xdf_sectors == 3)) { - dev->current_side_flags[side] = 0x28; - return(1); /* 5.25" 2HD XDF */ - } + if ((effective_sectors == 3) && (xdf_sectors == 3)) { + dev->current_side_flags[side] = 0x28; + return (1); /* 5.25" 2HD XDF */ + } - if ((effective_sectors == 4) && (xdf_sectors == 4)) { - dev->current_side_flags[side] = 0x08; - return(2); /* 3.5" 2HD XDF */ - } + if ((effective_sectors == 4) && (xdf_sectors == 4)) { + dev->current_side_flags[side] = 0x08; + return (2); /* 3.5" 2HD XDF */ + } } - return(0); + return (0); } - static int track_is_interleave(int drive, int side, int track) { td0_t *dev = td0[drive]; - int i, effective_sectors; - int track_spt; + int i, effective_sectors; + int track_spt; effective_sectors = 0; for (i = 0; i < 256; i++) - dev->interleave_ordered_pos[i][side] = 0; + dev->interleave_ordered_pos[i][side] = 0; track_spt = dev->track_spt[track][side]; - if (track_spt != 21) return(0); + if (track_spt != 21) + return (0); for (i = 0; i < track_spt; i++) { - if ((dev->sects[track][side][i].track == track) && (dev->sects[track][side][i].head == side) && (dev->sects[track][side][i].sector >= 1) && (dev->sects[track][side][i].sector <= track_spt) && (dev->sects[track][side][i].size == 2)) { - effective_sectors++; - dev->interleave_ordered_pos[dev->sects[track][side][i].sector][side] = i; - } + if ((dev->sects[track][side][i].track == track) && (dev->sects[track][side][i].head == side) && (dev->sects[track][side][i].sector >= 1) && (dev->sects[track][side][i].sector <= track_spt) && (dev->sects[track][side][i].size == 2)) { + effective_sectors++; + dev->interleave_ordered_pos[dev->sects[track][side][i].sector][side] = i; + } } - if (effective_sectors == track_spt) return(1); + if (effective_sectors == track_spt) + return (1); - return(0); + return (0); } - static void td0_seek(int drive, int track) { - td0_t *dev = td0[drive]; - int side; + td0_t *dev = td0[drive]; + int side; uint8_t id[4] = { 0, 0, 0, 0 }; - int sector, current_pos; - int ssize = 512; - int track_rate = 0; - int track_gap2 = 22; - int track_gap3 = 12; - int xdf_type = 0; - int interleave_type = 0; - int is_trackx = 0; - int xdf_spt = 0; - int xdf_sector = 0; - int ordered_pos = 0; - int real_sector = 0; - int actual_sector = 0; - int fm, sector_adjusted; + int sector, current_pos; + int ssize = 512; + int track_rate = 0; + int track_gap2 = 22; + int track_gap3 = 12; + int xdf_type = 0; + int interleave_type = 0; + int is_trackx = 0; + int xdf_spt = 0; + int xdf_sector = 0; + int ordered_pos = 0; + int real_sector = 0; + int actual_sector = 0; + int fm, sector_adjusted; - if (dev->f == NULL) return; + if (dev->f == NULL) + return; if (!dev->track_width && fdd_doublestep_40(drive)) - track /= 2; + track /= 2; d86f_set_cur_track(drive, track); - is_trackx = (track == 0) ? 0 : 1; + is_trackx = (track == 0) ? 0 : 1; dev->track = track; dev->current_side_flags[0] = dev->side_flags[track][0]; @@ -1081,172 +1060,169 @@ td0_seek(int drive, int track) d86f_destroy_linked_lists(drive, 1); if (track > dev->tracks) { - d86f_zero_track(drive); - return; + d86f_zero_track(drive); + return; } for (side = 0; side < dev->sides; side++) { - track_rate = dev->current_side_flags[side] & 7; - /* Make sure 300 kbps @ 360 rpm is treated the same as 250 kbps @ 300 rpm. */ - if (!track_rate && (dev->current_side_flags[side] & 0x20)) - track_rate = 4; - if ((dev->current_side_flags[side] & 0x27) == 0x21) - track_rate = 2; - track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; - if (! track_gap3) - track_gap3 = dev->calculated_gap3_lengths[track][side]; + track_rate = dev->current_side_flags[side] & 7; + /* Make sure 300 kbps @ 360 rpm is treated the same as 250 kbps @ 300 rpm. */ + if (!track_rate && (dev->current_side_flags[side] & 0x20)) + track_rate = 4; + if ((dev->current_side_flags[side] & 0x27) == 0x21) + track_rate = 2; + track_gap3 = gap3_sizes[track_rate][dev->sects[track][side][0].size][dev->track_spt[track][side]]; + if (!track_gap3) + track_gap3 = dev->calculated_gap3_lengths[track][side]; - track_gap2 = ((dev->current_side_flags[side] & 7) >= 3) ? 41 : 22; + track_gap2 = ((dev->current_side_flags[side] & 7) >= 3) ? 41 : 22; - xdf_type = track_is_xdf(drive, side, track); + xdf_type = track_is_xdf(drive, side, track); - interleave_type = track_is_interleave(drive, side, track); + interleave_type = track_is_interleave(drive, side, track); - current_pos = d86f_prepare_pretrack(drive, side, 0); - sector_adjusted = 0; + current_pos = d86f_prepare_pretrack(drive, side, 0); + sector_adjusted = 0; - if (! xdf_type) { - for (sector = 0; sector < dev->track_spt[track][side]; sector++) { - if (interleave_type == 0) { - real_sector = dev->sects[track][side][sector].sector; - actual_sector = sector; - } else { - real_sector = dmf_r[sector]; - actual_sector = dev->interleave_ordered_pos[real_sector][side]; - } + if (!xdf_type) { + for (sector = 0; sector < dev->track_spt[track][side]; sector++) { + if (interleave_type == 0) { + real_sector = dev->sects[track][side][sector].sector; + actual_sector = sector; + } else { + real_sector = dmf_r[sector]; + actual_sector = dev->interleave_ordered_pos[real_sector][side]; + } - id[0] = dev->sects[track][side][actual_sector].track; - id[1] = dev->sects[track][side][actual_sector].head; - id[2] = real_sector; - id[3] = dev->sects[track][side][actual_sector].size; - td0_log("track %i, side %i, %i,%i,%i,%i %i\n", track, side, id[0], id[1], id[2], id[3], dev->sects[track][side][actual_sector].flags); - fm = dev->sects[track][side][actual_sector].fm; - if (((dev->sects[track][side][actual_sector].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) - ssize = 3; - else - ssize = 128 << ((uint32_t) id[3]); - current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].flags); + id[0] = dev->sects[track][side][actual_sector].track; + id[1] = dev->sects[track][side][actual_sector].head; + id[2] = real_sector; + id[3] = dev->sects[track][side][actual_sector].size; + td0_log("track %i, side %i, %i,%i,%i,%i %i\n", track, side, id[0], id[1], id[2], id[3], dev->sects[track][side][actual_sector].flags); + fm = dev->sects[track][side][actual_sector].fm; + if (((dev->sects[track][side][actual_sector].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) + ssize = 3; + else + ssize = 128 << ((uint32_t) id[3]); + current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, dev->sects[track][side][actual_sector].flags); - if (sector_adjusted == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + if (sector_adjusted == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - if (!(dev->sects[track][side][actual_sector].flags & 0x40)) - sector_adjusted++; - } - } else { - xdf_type--; - xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; - for (sector = 0; sector < xdf_spt; sector++) { - xdf_sector = (side * xdf_spt) + sector; - id[0] = track; - id[1] = side; - id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; - id[3] = is_trackx ? (id[2] & 7) : 2; - ordered_pos = dev->xdf_ordered_pos[id[2]][side]; - fm = dev->sects[track][side][ordered_pos].fm; - if (((dev->sects[track][side][ordered_pos].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) - ssize = 3; - else - ssize = 128 << ((uint32_t) id[3]); - if (is_trackx) - current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); - else - current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); + if (!(dev->sects[track][side][actual_sector].flags & 0x40)) + sector_adjusted++; + } + } else { + xdf_type--; + xdf_spt = xdf_physical_sectors[xdf_type][is_trackx]; + for (sector = 0; sector < xdf_spt; sector++) { + xdf_sector = (side * xdf_spt) + sector; + id[0] = track; + id[1] = side; + id[2] = xdf_disk_layout[xdf_type][is_trackx][xdf_sector].id.r; + id[3] = is_trackx ? (id[2] & 7) : 2; + ordered_pos = dev->xdf_ordered_pos[id[2]][side]; + fm = dev->sects[track][side][ordered_pos].fm; + if (((dev->sects[track][side][ordered_pos].flags & 0x42) || (id[3] > (dev->max_sector_size - fm))) && !fdd_get_turbo(drive)) + ssize = 3; + else + ssize = 128 << ((uint32_t) id[3]); + if (is_trackx) + current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); + else + current_pos = d86f_prepare_sector(drive, side, current_pos, id, dev->sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], dev->sects[track][side][ordered_pos].flags); - if (sector_adjusted == 0) - d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); + if (sector_adjusted == 0) + d86f_initialize_last_sector_id(drive, id[0], id[1], id[2], id[3]); - if (!(dev->sects[track][side][ordered_pos].flags & 0x40)) - sector_adjusted++; - } - } + if (!(dev->sects[track][side][ordered_pos].flags & 0x40)) + sector_adjusted++; + } + } } } - void td0_init(void) { memset(td0, 0x00, sizeof(td0)); } - void td0_abort(int drive) { td0_t *dev = td0[drive]; if (dev->imagebuf) - free(dev->imagebuf); + free(dev->imagebuf); if (dev->processed_buf) - free(dev->processed_buf); + free(dev->processed_buf); if (dev->f) - fclose(dev->f); + fclose(dev->f); memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); free(dev); td0[drive] = NULL; } - void td0_load(int drive, char *fn) { - td0_t *dev; + td0_t *dev; uint32_t i; d86f_unregister(drive); writeprot[drive] = 1; - dev = (td0_t *)malloc(sizeof(td0_t)); + dev = (td0_t *) malloc(sizeof(td0_t)); memset(dev, 0x00, sizeof(td0_t)); td0[drive] = dev; dev->f = plat_fopen(fn, "rb"); if (dev->f == NULL) { - memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); - return; + memset(floppyfns[drive], 0, sizeof(floppyfns[drive])); + return; } fwriteprot[drive] = writeprot[drive]; - if (! dsk_identify(drive)) { - td0_log("TD0: Not a valid Teledisk image\n"); - td0_abort(drive); - return; + if (!dsk_identify(drive)) { + td0_log("TD0: Not a valid Teledisk image\n"); + td0_abort(drive); + return; } else { - td0_log("TD0: Valid Teledisk image\n"); + td0_log("TD0: Valid Teledisk image\n"); } /* Allocate the processing buffers. */ - i = 1024UL * 1024UL * 4UL; - dev->imagebuf = (uint8_t *)malloc(i); + i = 1024UL * 1024UL * 4UL; + dev->imagebuf = (uint8_t *) malloc(i); memset(dev->imagebuf, 0x00, i); - dev->processed_buf = (uint8_t *)malloc(i); + dev->processed_buf = (uint8_t *) malloc(i); memset(dev->processed_buf, 0x00, i); - if (! td0_initialize(drive)) { - td0_log("TD0: Failed to initialize\n"); - td0_abort(drive); - return; + if (!td0_initialize(drive)) { + td0_log("TD0: Failed to initialize\n"); + td0_abort(drive); + return; } else { - td0_log("TD0: Initialized successfully\n"); + td0_log("TD0: Initialized successfully\n"); } /* Attach this format to the D86F engine. */ - d86f_handler[drive].disk_flags = disk_flags; - d86f_handler[drive].side_flags = side_flags; - d86f_handler[drive].writeback = null_writeback; - d86f_handler[drive].set_sector = set_sector; - d86f_handler[drive].read_data = poll_read_data; - d86f_handler[drive].write_data = null_write_data; + d86f_handler[drive].disk_flags = disk_flags; + d86f_handler[drive].side_flags = side_flags; + d86f_handler[drive].writeback = null_writeback; + d86f_handler[drive].set_sector = set_sector; + d86f_handler[drive].read_data = poll_read_data; + d86f_handler[drive].write_data = null_write_data; d86f_handler[drive].format_conditions = null_format_conditions; - d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; - d86f_handler[drive].encoded_data = common_encoded_data; - d86f_handler[drive].read_revolution = common_read_revolution; - d86f_handler[drive].index_hole_pos = null_index_hole_pos; - d86f_handler[drive].get_raw_size = common_get_raw_size; - d86f_handler[drive].check_crc = 1; + d86f_handler[drive].extra_bit_cells = null_extra_bit_cells; + d86f_handler[drive].encoded_data = common_encoded_data; + d86f_handler[drive].read_revolution = common_read_revolution; + d86f_handler[drive].index_hole_pos = null_index_hole_pos; + d86f_handler[drive].get_raw_size = common_get_raw_size; + d86f_handler[drive].check_crc = 1; d86f_set_version(drive, 0x0063); drives[drive].seek = td0_seek; @@ -1254,39 +1230,39 @@ td0_load(int drive, char *fn) d86f_common_handlers(drive); } - void td0_close(int drive) { td0_t *dev = td0[drive]; - int i, j, k; + int i, j, k; - if (dev == NULL) return; + if (dev == NULL) + return; d86f_unregister(drive); if (dev->imagebuf) - free(dev->imagebuf); + free(dev->imagebuf); if (dev->processed_buf) - free(dev->processed_buf); + free(dev->processed_buf); for (i = 0; i < 256; i++) { - for (j = 0; j < 2; j++) { - for (k = 0; k < 256; k++) - dev->sects[i][j][k].data = NULL; - } + for (j = 0; j < 2; j++) { + for (k = 0; k < 256; k++) + dev->sects[i][j][k].data = NULL; + } } for (i = 0; i < 256; i++) { - memset(dev->side_flags[i], 0, 4); - memset(dev->track_in_file[i], 0, 2); - memset(dev->calculated_gap3_lengths[i], 0, 2); - for (j = 0; j < 2; j++) - memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); + memset(dev->side_flags[i], 0, 4); + memset(dev->track_in_file[i], 0, 2); + memset(dev->calculated_gap3_lengths[i], 0, 2); + for (j = 0; j < 2; j++) + memset(dev->sects[i][j], 0, sizeof(td0_sector_t)); } if (dev->f != NULL) - fclose(dev->f); + fclose(dev->f); /* Release resources. */ free(dev); diff --git a/src/game/gameport.c b/src/game/gameport.c index db11c0a0f..ab8422070 100644 --- a/src/game/gameport.c +++ b/src/game/gameport.c @@ -116,7 +116,7 @@ static uint8_t gameport_pnp_rom[] = { static const isapnp_device_config_t gameport_pnp_defaults[] = { {.activate = 1, .io = { - { .base = 0x200 }, + { .base = 0x200 }, }} }; @@ -642,7 +642,7 @@ static const device_config_t tmacm_config[] = { } }, { "", "", -1 } -// clang-format on + // clang-format on }; const device_t gameport_tm_acm_device = { diff --git a/src/game/joystick_ch_flightstick_pro.c b/src/game/joystick_ch_flightstick_pro.c index 2a6c52a7d..0741e0360 100644 --- a/src/game/joystick_ch_flightstick_pro.c +++ b/src/game/joystick_ch_flightstick_pro.c @@ -128,7 +128,7 @@ const joystick_if_t joystick_ch_flightstick_pro = { .button_count = 4, .pov_count = 1, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Throttle" }, + .axis_names = { "X axis", "Y axis", "Throttle" }, .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { "POV"} + .pov_names = { "POV" } }; diff --git a/src/game/joystick_standard.c b/src/game/joystick_standard.c index fa3b3e2e5..71c354945 100644 --- a/src/game/joystick_standard.c +++ b/src/game/joystick_standard.c @@ -251,9 +251,9 @@ const joystick_if_t joystick_2axis_2button = { .button_count = 2, .pov_count = 0, .max_joysticks = 2, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } }; const joystick_if_t joystick_2axis_4button = { @@ -269,9 +269,9 @@ const joystick_if_t joystick_2axis_4button = { .button_count = 4, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } }; const joystick_if_t joystick_3axis_2button = { @@ -287,9 +287,9 @@ const joystick_if_t joystick_3axis_2button = { .button_count = 2, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Z axis" }, - .button_names = { "Button 1", "Button 2" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis", "Z axis" }, + .button_names = { "Button 1", "Button 2" }, + .pov_names = { NULL } }; const joystick_if_t joystick_3axis_4button = { @@ -305,9 +305,9 @@ const joystick_if_t joystick_3axis_4button = { .button_count = 4, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Z axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis", "Z axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { NULL } }; const joystick_if_t joystick_4axis_4button = { @@ -323,9 +323,9 @@ const joystick_if_t joystick_4axis_4button = { .button_count = 4, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis", "Z axis", "zX axis" }, + .axis_names = { "X axis", "Y axis", "Z axis", "zX axis" }, .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { NULL } + .pov_names = { NULL } }; const joystick_if_t joystick_2axis_6button = { @@ -341,9 +341,9 @@ const joystick_if_t joystick_2axis_6button = { .button_count = 6, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6" }, + .pov_names = { NULL } }; const joystick_if_t joystick_2axis_8button = { @@ -359,7 +359,7 @@ const joystick_if_t joystick_2axis_8button = { .button_count = 8, .pov_count = 0, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8" }, + .pov_names = { NULL } }; diff --git a/src/game/joystick_sw_pad.c b/src/game/joystick_sw_pad.c index 8f4c804e2..647ca6a74 100644 --- a/src/game/joystick_sw_pad.c +++ b/src/game/joystick_sw_pad.c @@ -266,7 +266,7 @@ const joystick_if_t joystick_sw_pad = { .button_count = 10, .pov_count = 0, .max_joysticks = 4, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M" }, - .pov_names = { NULL} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M" }, + .pov_names = { NULL } }; diff --git a/src/game/joystick_tm_fcs.c b/src/game/joystick_tm_fcs.c index 63ebdbda8..4364a432f 100644 --- a/src/game/joystick_tm_fcs.c +++ b/src/game/joystick_tm_fcs.c @@ -128,7 +128,7 @@ const joystick_if_t joystick_tm_fcs = { .button_count = 4, .pov_count = 1, .max_joysticks = 1, - .axis_names = {"X axis", "Y axis" }, - .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, - .pov_names = { "POV"} + .axis_names = { "X axis", "Y axis" }, + .button_names = { "Button 1", "Button 2", "Button 3", "Button 4" }, + .pov_names = { "POV" } }; diff --git a/src/include/86box/bswap.h b/src/include/86box/bswap.h index 95be57e61..22d25cf4a 100644 --- a/src/include/86box/bswap.h +++ b/src/include/86box/bswap.h @@ -36,12 +36,12 @@ */ #ifndef BSWAP_H -# define BSWAP_H +#define BSWAP_H #include #ifdef HAVE_BYTESWAP_H -#include +# include #else # define bswap_16(x) \ ( \ @@ -81,103 +81,111 @@ static __inline uint16_t bswap16(uint16_t x) { return bswap_16(x); } -#endif +# endif #else -static __inline uint16_t bswap16(uint16_t x) +static __inline uint16_t +bswap16(uint16_t x) { return bswap_16(x); } #endif -#if __GNUC__ >= 10 -#if defined __has_builtin && __has_builtin(__builtin_bswap32) -#define bswap32(x) __builtin_bswap32(x) -#else -static __inline uint32_t bswap32(uint32_t x) +#if __GNUC__ >= 10 +# if defined __has_builtin && __has_builtin(__builtin_bswap32) +# define bswap32(x) __builtin_bswap32(x) +# else +static __inline uint32_t +bswap32(uint32_t x) { return bswap_32(x); } -#endif +# endif #else -static __inline uint32_t bswap32(uint32_t x) +static __inline uint32_t +bswap32(uint32_t x) { return bswap_32(x); } #endif -#if __GNUC__ >= 10 -#if defined __has_builtin && __has_builtin(__builtin_bswap64) -#define bswap64(x) __builtin_bswap64(x) -#else -static __inline uint64_t bswap64(uint64_t x) +#if __GNUC__ >= 10 +# if defined __has_builtin && __has_builtin(__builtin_bswap64) +# define bswap64(x) __builtin_bswap64(x) +# else +static __inline uint64_t +bswap64(uint64_t x) { return bswap_64(x); } -#endif +# endif #else -static __inline uint64_t bswap64(uint64_t x) +static __inline uint64_t +bswap64(uint64_t x) { return bswap_64(x); } #endif -static __inline void bswap16s(uint16_t *s) +static __inline void +bswap16s(uint16_t *s) { *s = bswap16(*s); } -static __inline void bswap32s(uint32_t *s) +static __inline void +bswap32s(uint32_t *s) { *s = bswap32(*s); } -static __inline void bswap64s(uint64_t *s) +static __inline void +bswap64s(uint64_t *s) { *s = bswap64(*s); } #if defined(WORDS_BIGENDIAN) -# define be_bswap(v, size) (v) -# define le_bswap(v, size) bswap ## size(v) -# define be_bswaps(v, size) -# define le_bswaps(p, size) *p = bswap ## size(*p); +# define be_bswap(v, size) (v) +# define le_bswap(v, size) bswap##size(v) +# define be_bswaps(v, size) +# define le_bswaps(p, size) *p = bswap##size(*p); #else -# define le_bswap(v, size) (v) -# define be_bswap(v, size) bswap ## size(v) -# define le_bswaps(v, size) -# define be_bswaps(p, size) *p = bswap ## size(*p); +# define le_bswap(v, size) (v) +# define be_bswap(v, size) bswap##size(v) +# define le_bswaps(v, size) +# define be_bswaps(p, size) *p = bswap##size(*p); #endif -#define CPU_CONVERT(endian, size, type)\ -static __inline type endian ## size ## _to_cpu(type v)\ -{\ - return endian ## _bswap(v, size);\ -}\ -\ -static __inline type cpu_to_ ## endian ## size(type v)\ -{\ - return endian ## _bswap(v, size);\ -}\ -\ -static __inline void endian ## size ## _to_cpus(type *p)\ -{\ - endian ## _bswaps(p, size)\ -}\ -\ -static __inline void cpu_to_ ## endian ## size ## s(type *p)\ -{\ - endian ## _bswaps(p, size)\ -}\ -\ -static __inline type endian ## size ## _to_cpup(const type *p)\ -{\ - return endian ## size ## _to_cpu(*p);\ -}\ -\ -static __inline void cpu_to_ ## endian ## size ## w(type *p, type v)\ -{\ - *p = cpu_to_ ## endian ## size(v);\ -} +#define CPU_CONVERT(endian, size, type) \ + static __inline type endian##size##_to_cpu(type v) \ + { \ + return endian##_bswap(v, size); \ + } \ + \ + static __inline type cpu_to_##endian##size(type v) \ + { \ + return endian##_bswap(v, size); \ + } \ + \ + static __inline void endian##size##_to_cpus(type *p) \ + { \ + endian##_bswaps(p, size) \ + } \ + \ + static __inline void cpu_to_##endian##size##s(type *p) \ + { \ + endian##_bswaps(p, size) \ + } \ + \ + static __inline type endian##size##_to_cpup(const type *p) \ + { \ + return endian##size##_to_cpu(*p); \ + } \ + \ + static __inline void cpu_to_##endian##size##w(type *p, type v) \ + { \ + *p = cpu_to_##endian##size(v); \ + } CPU_CONVERT(be, 16, uint16_t) CPU_CONVERT(be, 32, uint32_t) @@ -191,27 +199,29 @@ CPU_CONVERT(le, 64, uint64_t) #if defined(__i386__) || defined(__powerpc__) -#define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) -#define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) -#define le16_to_cpupu(p) le16_to_cpup(p) -#define le32_to_cpupu(p) le32_to_cpup(p) +# define cpu_to_le16wu(p, v) cpu_to_le16w(p, v) +# define cpu_to_le32wu(p, v) cpu_to_le32w(p, v) +# define le16_to_cpupu(p) le16_to_cpup(p) +# define le32_to_cpupu(p) le32_to_cpup(p) -#define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) -#define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) +# define cpu_to_be16wu(p, v) cpu_to_be16w(p, v) +# define cpu_to_be32wu(p, v) cpu_to_be32w(p, v) #else -static __inline void cpu_to_le16wu(uint16_t *p, uint16_t v) +static __inline void +cpu_to_le16wu(uint16_t *p, uint16_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v & 0xff; p1[1] = v >> 8; } -static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v) +static __inline void +cpu_to_le32wu(uint32_t *p, uint32_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v; p1[1] = v >> 8; @@ -219,29 +229,33 @@ static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v) p1[3] = v >> 24; } -static __inline uint16_t le16_to_cpupu(const uint16_t *p) +static __inline uint16_t +le16_to_cpupu(const uint16_t *p) { - const uint8_t *p1 = (const uint8_t *)p; + const uint8_t *p1 = (const uint8_t *) p; return p1[0] | (p1[1] << 8); } -static __inline uint32_t le32_to_cpupu(const uint32_t *p) +static __inline uint32_t +le32_to_cpupu(const uint32_t *p) { - const uint8_t *p1 = (const uint8_t *)p; + const uint8_t *p1 = (const uint8_t *) p; return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24); } -static __inline void cpu_to_be16wu(uint16_t *p, uint16_t v) +static __inline void +cpu_to_be16wu(uint16_t *p, uint16_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v >> 8; p1[1] = v & 0xff; } -static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) +static __inline void +cpu_to_be32wu(uint32_t *p, uint32_t v) { - uint8_t *p1 = (uint8_t *)p; + uint8_t *p1 = (uint8_t *) p; p1[0] = v >> 24; p1[1] = v >> 16; @@ -252,9 +266,9 @@ static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) #endif #ifdef WORDS_BIGENDIAN -#define cpu_to_32wu cpu_to_be32wu +# define cpu_to_32wu cpu_to_be32wu #else -#define cpu_to_32wu cpu_to_le32wu +# define cpu_to_32wu cpu_to_le32wu #endif #undef le_bswap diff --git a/src/include/86box/fdc.h b/src/include/86box/fdc.h index 3d21e9f9e..ec3136baa 100644 --- a/src/include/86box/fdc.h +++ b/src/include/86box/fdc.h @@ -40,18 +40,18 @@ extern int fdc_type; #define FDC_QUATERNARY_IRQ 6 #define FDC_QUATERNARY_DMA 2 -#define FDC_FLAG_PCJR 0x01 /* PCjr */ -#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ -#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ -#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ -#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ -#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ -#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ -#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ -#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ -#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ -#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ -#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ +#define FDC_FLAG_PCJR 0x01 /* PCjr */ +#define FDC_FLAG_DISKCHG_ACTLOW 0x02 /* Amstrad, PS/1, PS/2 ISA */ +#define FDC_FLAG_AT 0x04 /* AT+, PS/x */ +#define FDC_FLAG_PS1 0x08 /* PS/1, PS/2 ISA */ +#define FDC_FLAG_SUPERIO 0x10 /* Super I/O chips */ +#define FDC_FLAG_START_RWC_1 0x20 /* W83877F, W83977F */ +#define FDC_FLAG_MORE_TRACKS 0x40 /* W83877F, W83977F, PC87306, PC87309 */ +#define FDC_FLAG_NSC 0x80 /* PC87306, PC87309 */ +#define FDC_FLAG_TOSHIBA 0x100 /* T1000, T1200 */ +#define FDC_FLAG_AMSTRAD 0x200 /* Non-AT Amstrad machines */ +#define FDC_FLAG_UMC 0x400 /* UMC UM8398 */ +#define FDC_FLAG_ALI 0x800 /* ALi M512x / M1543C */ #define FDC_FLAG_SEC 0x1000 /* Is Secondary */ typedef struct { diff --git a/src/include/86box/fdd.h b/src/include/86box/fdd.h index 412843eb0..f612466b3 100644 --- a/src/include/86box/fdd.h +++ b/src/include/86box/fdd.h @@ -21,9 +21,9 @@ #ifndef EMU_FDD_H #define EMU_FDD_H -#define FDD_NUM 4 -#define FLOPPY_IMAGE_HISTORY 4 -#define SEEK_RECALIBRATE -999 +#define FDD_NUM 4 +#define FLOPPY_IMAGE_HISTORY 4 +#define SEEK_RECALIBRATE -999 #ifdef __cplusplus extern "C" { @@ -85,7 +85,7 @@ typedef struct { extern DRIVE drives[FDD_NUM]; extern char floppyfns[FDD_NUM][512]; -extern char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; +extern char *fdd_image_history[FDD_NUM][FLOPPY_IMAGE_HISTORY]; extern pc_timer_t fdd_poll_time[FDD_NUM]; extern int ui_writeprot[FDD_NUM]; diff --git a/src/include/86box/hdc.h b/src/include/86box/hdc.h index 0f56aa374..68b75b97b 100644 --- a/src/include/86box/hdc.h +++ b/src/include/86box/hdc.h @@ -33,19 +33,19 @@ extern int hdc_current; -extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */ -extern const device_t st506_xt_dtc5150x_device; /* st506_xt_dtc */ -extern const device_t st506_xt_st11_m_device; /* st506_xt_st11_m */ -extern const device_t st506_xt_st11_r_device; /* st506_xt_st11_m */ -extern const device_t st506_xt_wd1002a_wx1_device; /* st506_xt_wd1002a_wx1 */ -extern const device_t st506_xt_wd1002a_wx1_nobios_device; /* st506_xt_wd1002a_wx1 */ -extern const device_t st506_xt_wd1002a_27x_device; /* st506_xt_wd1002a_27x */ -extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */ -extern const device_t st506_xt_wd1004a_wx1_device; /* st506_xt_wd1004a_wx1 */ -extern const device_t st506_xt_wd1004_27x_device; /* st506_xt_wd1004_27x */ -extern const device_t st506_xt_wd1004a_27x_device; /* st506_xt_wd1004a_27x */ -extern const device_t st506_xt_victor_v86p_device; /* st506_xt_victor_v86p */ -extern const device_t st506_xt_toshiba_t1200_device; /* st506_xt_toshiba_t1200 */ +extern const device_t st506_xt_xebec_device; /* st506_xt_xebec */ +extern const device_t st506_xt_dtc5150x_device; /* st506_xt_dtc */ +extern const device_t st506_xt_st11_m_device; /* st506_xt_st11_m */ +extern const device_t st506_xt_st11_r_device; /* st506_xt_st11_m */ +extern const device_t st506_xt_wd1002a_wx1_device; /* st506_xt_wd1002a_wx1 */ +extern const device_t st506_xt_wd1002a_wx1_nobios_device; /* st506_xt_wd1002a_wx1 */ +extern const device_t st506_xt_wd1002a_27x_device; /* st506_xt_wd1002a_27x */ +extern const device_t st506_at_wd1003_device; /* st506_at_wd1003 */ +extern const device_t st506_xt_wd1004a_wx1_device; /* st506_xt_wd1004a_wx1 */ +extern const device_t st506_xt_wd1004_27x_device; /* st506_xt_wd1004_27x */ +extern const device_t st506_xt_wd1004a_27x_device; /* st506_xt_wd1004a_27x */ +extern const device_t st506_xt_victor_v86p_device; /* st506_xt_victor_v86p */ +extern const device_t st506_xt_toshiba_t1200_device; /* st506_xt_toshiba_t1200 */ extern const device_t esdi_at_wd1007vse1_device; /* esdi_at */ extern const device_t esdi_ps2_device; /* esdi_mca */ diff --git a/src/include/86box/hdd.h b/src/include/86box/hdd.h index 3774f6f37..abb2aa388 100644 --- a/src/include/86box/hdd.h +++ b/src/include/86box/hdd.h @@ -18,14 +18,14 @@ #ifndef EMU_HDD_H #define EMU_HDD_H -#define IMG_FMT_RAW 0 -#define IMG_FMT_HDI 1 -#define IMG_FMT_HDX 2 -#define IMG_FMT_VHD_FIXED 3 +#define IMG_FMT_RAW 0 +#define IMG_FMT_HDI 1 +#define IMG_FMT_HDX 2 +#define IMG_FMT_VHD_FIXED 3 #define IMG_FMT_VHD_DYNAMIC 4 -#define IMG_FMT_VHD_DIFF 5 +#define IMG_FMT_VHD_DIFF 5 -#define HDD_NUM 88 /* total of 88 images supported */ +#define HDD_NUM 88 /* total of 88 images supported */ /* Hard Disk bus types. */ #if 0 diff --git a/src/include/86box/i8080.h b/src/include/86box/i8080.h index 1fa01b998..9f85a85c0 100644 --- a/src/include/86box/i8080.h +++ b/src/include/86box/i8080.h @@ -15,32 +15,36 @@ #include -typedef struct i8080 -{ - union { +typedef struct i8080 { + union { uint16_t af; /* Intended in case we also go for μPD9002 emulation, which also has a Z80 emulation mode. */ - struct { uint8_t a, flags; }; + struct { + uint8_t a, flags; + }; }; - union - { + union { uint16_t bc; - struct { uint8_t b, c; }; + struct { + uint8_t b, c; + }; }; - union - { + union { uint16_t de; - struct { uint8_t d, e; }; + struct { + uint8_t d, e; + }; }; - union - { + union { uint16_t hl; - struct { uint8_t h, l; }; + struct { + uint8_t h, l; + }; }; - uint16_t pc, sp; - uint16_t oldpc, ei; - uint32_t pmembase, dmembase; /* Base from where i8080 starts. */ - uint8_t emulated; /* 0 = not emulated, use separate registers, 1 = emulated, use x86 registers. */ - uint16_t* cpu_flags; + uint16_t pc, sp; + uint16_t oldpc, ei; + uint32_t pmembase, dmembase; /* Base from where i8080 starts. */ + uint8_t emulated; /* 0 = not emulated, use separate registers, 1 = emulated, use x86 registers. */ + uint16_t *cpu_flags; void (*writemembyte)(uint32_t, uint8_t); uint8_t (*readmembyte)(uint32_t); void (*startclock)(void); @@ -49,8 +53,8 @@ typedef struct i8080 uint8_t (*fetchinstruction)(void *); } i8080; -#define C_FLAG_I8080 (1 << 0) -#define P_FLAG_I8080 (1 << 2) +#define C_FLAG_I8080 (1 << 0) +#define P_FLAG_I8080 (1 << 2) #define AC_FLAG_I8080 (1 << 4) -#define Z_FLAG_I8080 (1 << 6) -#define S_FLAG_I8080 (1 << 7) +#define Z_FLAG_I8080 (1 << 6) +#define S_FLAG_I8080 (1 << 7) diff --git a/src/include/86box/language.h b/src/include/86box/language.h index 4a983a1c8..90bfecc06 100644 --- a/src/include/86box/language.h +++ b/src/include/86box/language.h @@ -22,65 +22,65 @@ #define LANG_UAGE_H /* String IDs. */ -#define IDS_STRINGS 2048 // "86Box" -#define IDS_2049 2049 // "Error" -#define IDS_2050 2050 // "Fatal error" -#define IDS_2051 2051 // " - PAUSED" -#define IDS_2052 2052 // "Press Ctrl+Alt+PgDn..." -#define IDS_2053 2053 // "Speed" -#define IDS_2054 2054 // "ZIP %i (%03i): %ls" -#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2056 2056 // "No usable ROM images found!" -#define IDS_2057 2057 // "(empty)" -#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." -#define IDS_2059 2059 // "(Turbo)" -#define IDS_2060 2060 // "On" -#define IDS_2061 2061 // "Off" -#define IDS_2062 2062 // "All floppy images (*.DSK..." -#define IDS_2063 2063 // "Machine ""%hs"" is not..." -#define IDS_2064 2064 // "Video card ""%hs"" is not..." -#define IDS_2065 2065 // "Machine" -#define IDS_2066 2066 // "Display" -#define IDS_2067 2067 // "Input devices" -#define IDS_2068 2068 // "Sound" -#define IDS_2069 2069 // "Network" -#define IDS_2070 2070 // "Ports (COM & LPT)" -#define IDS_2071 2071 // "Storage controllers" -#define IDS_2072 2072 // "Hard disks" -#define IDS_2073 2073 // "Floppy and CD-ROM drives" -#define IDS_2074 2074 // "Other removable devices" -#define IDS_2075 2075 // "Other peripherals" -#define IDS_2076 2076 // "Surface-based images (*.8.." -#define IDS_2077 2077 // "Click to capture mouse" -#define IDS_2078 2078 // "Press F12-F8 to release mouse" -#define IDS_2079 2079 // "Press F12-F8 or middle button.." -#define IDS_2080 2080 // "Unable to initialize Flui.." -#define IDS_2081 2081 // "Bus" -#define IDS_BUS IDS_2081 // "Bus" -#define IDS_2082 2082 // "File" -#define IDS_2083 2083 // "C" -#define IDS_2084 2084 // "H" -#define IDS_2085 2085 // "S" -#define IDS_2086 2086 // "MB" -#define IDS_MB IDS_2086 // "MB" -#define IDS_2087 2087 // "Speed" +#define IDS_STRINGS 2048 // "86Box" +#define IDS_2049 2049 // "Error" +#define IDS_2050 2050 // "Fatal error" +#define IDS_2051 2051 // " - PAUSED" +#define IDS_2052 2052 // "Press Ctrl+Alt+PgDn..." +#define IDS_2053 2053 // "Speed" +#define IDS_2054 2054 // "ZIP %i (%03i): %ls" +#define IDS_2055 2055 // "ZIP images (*.IM?)\0*.IM..." +#define IDS_2056 2056 // "No usable ROM images found!" +#define IDS_2057 2057 // "(empty)" +#define IDS_2058 2058 // "ZIP images (*.IM?)\0*.IM..." +#define IDS_2059 2059 // "(Turbo)" +#define IDS_2060 2060 // "On" +#define IDS_2061 2061 // "Off" +#define IDS_2062 2062 // "All floppy images (*.DSK..." +#define IDS_2063 2063 // "Machine ""%hs"" is not..." +#define IDS_2064 2064 // "Video card ""%hs"" is not..." +#define IDS_2065 2065 // "Machine" +#define IDS_2066 2066 // "Display" +#define IDS_2067 2067 // "Input devices" +#define IDS_2068 2068 // "Sound" +#define IDS_2069 2069 // "Network" +#define IDS_2070 2070 // "Ports (COM & LPT)" +#define IDS_2071 2071 // "Storage controllers" +#define IDS_2072 2072 // "Hard disks" +#define IDS_2073 2073 // "Floppy and CD-ROM drives" +#define IDS_2074 2074 // "Other removable devices" +#define IDS_2075 2075 // "Other peripherals" +#define IDS_2076 2076 // "Surface-based images (*.8.." +#define IDS_2077 2077 // "Click to capture mouse" +#define IDS_2078 2078 // "Press F12-F8 to release mouse" +#define IDS_2079 2079 // "Press F12-F8 or middle button.." +#define IDS_2080 2080 // "Unable to initialize Flui.." +#define IDS_2081 2081 // "Bus" +#define IDS_BUS IDS_2081 // "Bus" +#define IDS_2082 2082 // "File" +#define IDS_2083 2083 // "C" +#define IDS_2084 2084 // "H" +#define IDS_2085 2085 // "S" +#define IDS_2086 2086 // "MB" +#define IDS_MB IDS_2086 // "MB" +#define IDS_2087 2087 // "Speed" -#define IDS_2088 2088 // "Check BPB" -#define IDS_BPB IDS_2088 // "Check BPB" +#define IDS_2088 2088 // "Check BPB" +#define IDS_BPB IDS_2088 // "Check BPB" -#define IDS_2089 2089 // "KB" -#define IDS_KB IDS_2089 // "KB" +#define IDS_2089 2089 // "KB" +#define IDS_KB IDS_2089 // "KB" -#define IDS_2090 2090 // "Could not initialize the video..." +#define IDS_2090 2090 // "Could not initialize the video..." -#define IDS_2091 2091 // "Default" -#define IDS_DEFAULT IDS_2091 // "Default" +#define IDS_2091 2091 // "Default" +#define IDS_DEFAULT IDS_2091 // "Default" -#define IDS_2092 2092 // "%i Wait state(s)" -#define IDS_WS IDS_2092 // "%i Wait state(s)" +#define IDS_2092 2092 // "%i Wait state(s)" +#define IDS_WS IDS_2092 // "%i Wait state(s)" -#define IDS_2093 2093 // "Type" -#define IDS_TYPE IDS_2093 // "Type" +#define IDS_2093 2093 // "Type" +#define IDS_TYPE IDS_2093 // "Type" /* TODO */ #define IDS_2094 2094 // "PCap failed to set up.." @@ -262,14 +262,14 @@ #define STR_NUM_2048 115 // UNUSED: #define STR_NUM_3072 11 -#define STR_NUM_4096 40 -#define STR_NUM_4352 6 -#define STR_NUM_4608 6 -#define STR_NUM_5120 1 -#define STR_NUM_5376 7 -#define STR_NUM_5632 7 -#define STR_NUM_5888 24 -#define STR_NUM_6144 4 -#define STR_NUM_7168 1 +#define STR_NUM_4096 40 +#define STR_NUM_4352 6 +#define STR_NUM_4608 6 +#define STR_NUM_5120 1 +#define STR_NUM_5376 7 +#define STR_NUM_5632 7 +#define STR_NUM_5888 24 +#define STR_NUM_6144 4 +#define STR_NUM_7168 1 #endif /*LANG_UAGE_H*/ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index aeca2e900..207cbde62 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -127,7 +127,10 @@ #define IS_AT(m) (((machines[m].bus_flags & (MACHINE_BUS_ISA16 | MACHINE_BUS_EISA | MACHINE_BUS_VLB | MACHINE_BUS_MCA | MACHINE_BUS_PCI | MACHINE_BUS_PCMCIA | MACHINE_BUS_AGP | MACHINE_BUS_AC97)) && !(machines[m].bus_flags & MACHINE_PC98)) ? 1 : 0) #define CPU_BLOCK(...) \ - (const uint8_t[]) { __VA_ARGS__, 0 } + (const uint8_t[]) \ + { \ + __VA_ARGS__, 0 \ + } #define MACHINE_MULTIPLIER_FIXED -1 #define CPU_BLOCK_NONE 0 diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index 2379496dc..5c24bebf2 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -22,38 +22,38 @@ #ifndef EMU_PCI_H #define EMU_PCI_H -#define PCI_REG_COMMAND 0x04 +#define PCI_REG_COMMAND 0x04 -#define PCI_COMMAND_IO 0x01 -#define PCI_COMMAND_MEM 0x02 +#define PCI_COMMAND_IO 0x01 +#define PCI_COMMAND_MEM 0x02 -#define PCI_NO_IRQ_STEERING 0x8000 -#define PCI_CAN_SWITCH_TYPE 0x10000 -#define PCI_NO_BRIDGES 0x20000 -#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 +#define PCI_NO_IRQ_STEERING 0x8000 +#define PCI_CAN_SWITCH_TYPE 0x10000 +#define PCI_NO_BRIDGES 0x20000 +#define PCI_ALWAYS_EXPOSE_DEV0 0x40000 -#define PCI_CONFIG_TYPE_1 1 -#define PCI_CONFIG_TYPE_2 2 +#define PCI_CONFIG_TYPE_1 1 +#define PCI_CONFIG_TYPE_2 2 -#define PCI_CONFIG_TYPE_MASK 0x7fff +#define PCI_CONFIG_TYPE_MASK 0x7fff -#define PCI_INTA 1 -#define PCI_INTB 2 -#define PCI_INTC 3 -#define PCI_INTD 4 +#define PCI_INTA 1 +#define PCI_INTB 2 +#define PCI_INTC 3 +#define PCI_INTD 4 -#define PCI_MIRQ0 0 -#define PCI_MIRQ1 1 -#define PCI_MIRQ2 2 -#define PCI_MIRQ3 3 -#define PCI_MIRQ4 4 -#define PCI_MIRQ5 5 -#define PCI_MIRQ6 6 -#define PCI_MIRQ7 7 +#define PCI_MIRQ0 0 +#define PCI_MIRQ1 1 +#define PCI_MIRQ2 2 +#define PCI_MIRQ3 3 +#define PCI_MIRQ4 4 +#define PCI_MIRQ5 5 +#define PCI_MIRQ6 6 +#define PCI_MIRQ7 7 -#define PCI_IRQ_DISABLED -1 +#define PCI_IRQ_DISABLED -1 -#define PCI_ADD_STRICT 0x80 +#define PCI_ADD_STRICT 0x80 enum { PCI_CARD_NORTHBRIDGE = 0, diff --git a/src/include/86box/plat.h b/src/include/86box/plat.h index ce058cb24..3f9b4ff75 100644 --- a/src/include/86box/plat.h +++ b/src/include/86box/plat.h @@ -49,7 +49,7 @@ extern int strnicmp(const char *s1, const char *s2, size_t n); # define ftello64 ftello # define off64_t off_t #elif defined(_MSC_VER) -//# define fopen64 fopen +// # define fopen64 fopen # define fseeko64 _fseeki64 # define ftello64 _ftelli64 # define off64_t off_t diff --git a/src/include/86box/plat_dir.h b/src/include/86box/plat_dir.h index 7a7876ebb..74caac23f 100644 --- a/src/include/86box/plat_dir.h +++ b/src/include/86box/plat_dir.h @@ -19,24 +19,24 @@ /* Windows needs the POSIX re-implementations */ #if defined(_WIN32) -#ifdef _MAX_FNAME -# define MAXNAMLEN _MAX_FNAME -#else -# define MAXNAMLEN 15 -#endif -#define MAXDIRLEN 127 +# ifdef _MAX_FNAME +# define MAXNAMLEN _MAX_FNAME +# else +# define MAXNAMLEN 15 +# endif +# define MAXDIRLEN 127 struct dirent { long d_ino; unsigned short d_reclen; unsigned short d_off; -#ifdef UNICODE +# ifdef UNICODE wchar_t d_name[MAXNAMLEN + 1]; -#else +# else char d_name[MAXNAMLEN + 1]; -#endif +# endif }; -#define d_namlen d_reclen +# define d_namlen d_reclen typedef struct { short flags; /* internal flags */ @@ -44,18 +44,18 @@ typedef struct { long handle; /* open handle to Win32 system */ short sts; /* last known status code */ char *dta; /* internal work data */ -#ifdef UNICODE +# ifdef UNICODE wchar_t dir[MAXDIRLEN + 1]; /* open dir */ -#else +# else char dir[MAXDIRLEN + 1]; /* open dir */ -#endif +# endif struct dirent dent; /* actual directory entry */ } DIR; /* Directory routine flags. */ -#define DIR_F_LOWER 0x0001 /* force to lowercase */ -#define DIR_F_SANE 0x0002 /* force this to sane path */ -#define DIR_F_ISROOT 0x0010 /* this is the root directory */ +# define DIR_F_LOWER 0x0001 /* force to lowercase */ +# define DIR_F_SANE 0x0002 /* force this to sane path */ +# define DIR_F_ISROOT 0x0010 /* this is the root directory */ /* Function prototypes. */ extern DIR *opendir(const char *); @@ -64,11 +64,10 @@ extern long telldir(DIR *); extern void seekdir(DIR *, long); extern int closedir(DIR *); -#define rewinddir(dirp) seekdir(dirp, 0L) +# define rewinddir(dirp) seekdir(dirp, 0L) #else /* On linux and macOS, use the standard functions and types */ -#include +# include #endif - #endif /*PLAT_DIR_H*/ diff --git a/src/include/86box/resource.h b/src/include/86box/resource.h index 82cfde082..dc54b504f 100644 --- a/src/include/86box/resource.h +++ b/src/include/86box/resource.h @@ -137,11 +137,11 @@ #define IDT_CD_SPEED 1761 /* Speed: */ /* DLG_CFG_OTHER_REMOVABLE_DEVICES */ -#define IDT_MO_DRIVES 1762 /* MO drives: */ -#define IDT_MO_BUS 1763 /* Bus: */ -#define IDT_MO_ID 1764 /* ID: */ -#define IDT_MO_CHANNEL 1765 /* Channel */ -#define IDT_MO_TYPE 1766 /* Type: */ +#define IDT_MO_DRIVES 1762 /* MO drives: */ +#define IDT_MO_BUS 1763 /* Bus: */ +#define IDT_MO_ID 1764 /* ID: */ +#define IDT_MO_CHANNEL 1765 /* Channel */ +#define IDT_MO_TYPE 1766 /* Type: */ #define IDT_ZIP_DRIVES 1767 /* ZIP drives: */ #define IDT_ZIP_BUS 1768 /* Bus: */ diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index a8cef77fe..4421840d6 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -68,8 +68,8 @@ void cga_poll(void *p); #ifdef EMU_DEVICE_H extern const device_config_t cga_config[]; -extern const device_t cga_device; -extern const device_t cga_pravetz_device; +extern const device_t cga_device; +extern const device_t cga_pravetz_device; #endif #endif /*VIDEO_CGA_H*/ diff --git a/src/include/86box/vid_cga_comp.h b/src/include/86box/vid_cga_comp.h index bbde070c1..f4dd58b40 100644 --- a/src/include/86box/vid_cga_comp.h +++ b/src/include/86box/vid_cga_comp.h @@ -23,7 +23,7 @@ #define Bit8u uint8_t #define Bit32u uint32_t #define Bitu unsigned int -#define bool uint8_t +#define bool uint8_t void update_cga16_color(uint8_t cgamode); void cga_comp_init(int revision); diff --git a/src/include/86box/vid_voodoo_codegen_x86.h b/src/include/86box/vid_voodoo_codegen_x86.h index 9432fa3b3..c04330190 100644 --- a/src/include/86box/vid_voodoo_codegen_x86.h +++ b/src/include/86box/vid_voodoo_codegen_x86.h @@ -2075,12 +2075,12 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x05); addlong((uint32_t) &xmm_ff_b); } - //#if 0 - // addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ - // addbyte(0x0f); - // addbyte(0x7e); - // addbyte(0x87); - // addlong(offsetof(voodoo_state_t, out)); + // #if 0 + // addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ + // addbyte(0x0f); + // addbyte(0x7e); + // addbyte(0x87); + // addlong(offsetof(voodoo_state_t, out)); if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) { addbyte(0x66); /*MOVD XMM3, params->fogColor[ESI]*/ @@ -2695,7 +2695,7 @@ voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, addbyte(0x67); addbyte(0xc0); } - //#endif + // #endif // addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ // addbyte(0x54); diff --git a/src/include/86box/vid_voodoo_common.h b/src/include/86box/vid_voodoo_common.h index ab55cc9f4..e6d4ad5e4 100644 --- a/src/include/86box/vid_voodoo_common.h +++ b/src/include/86box/vid_voodoo_common.h @@ -33,10 +33,10 @@ #define TEX_CACHE_MAX 64 #ifdef __cplusplus -#include +# include using atomic_int = std::atomic; #else -#include +# include #endif enum { @@ -320,7 +320,7 @@ typedef struct voodoo_t { uint32_t cmdfifo_amin, cmdfifo_amax; int cmdfifo_holecount; - atomic_uint cmd_status; + atomic_uint cmd_status; uint32_t sSetupMode; vert_t verts[4]; diff --git a/src/include/86box/vid_voodoo_dither.h b/src/include/86box/vid_voodoo_dither.h index 1b95e7e80..2d674c5b4 100644 --- a/src/include/86box/vid_voodoo_dither.h +++ b/src/include/86box/vid_voodoo_dither.h @@ -17,7 +17,7 @@ */ #ifndef VIDEO_VOODOO_DITHER_H -# define VIDEO_VOODOO_DITHER_H +#define VIDEO_VOODOO_DITHER_H static const uint8_t dither_rb[256][4][4] = { diff --git a/src/include/fdi2raw.h b/src/include/fdi2raw.h index 8f71679a8..7a53d9d17 100644 --- a/src/include/fdi2raw.h +++ b/src/include/fdi2raw.h @@ -21,7 +21,7 @@ #ifndef __FDI2RAW_H #define __FDI2RAW_H -#define uae_u8 uint8_t +#define uae_u8 uint8_t #define uae_u16 uint16_t #define uae_u32 uint32_t @@ -32,20 +32,20 @@ typedef struct fdi FDI; extern "C" { #endif -extern int fdi2raw_loadtrack (FDI*, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffset, int *multirev, int mfm); +extern int fdi2raw_loadtrack(FDI *, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int *indexoffset, int *multirev, int mfm); -extern int fdi2raw_loadrevolution (FDI*, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm); +extern int fdi2raw_loadrevolution(FDI *, uae_u16 *mfmbuf, uae_u16 *tracktiming, int track, int *tracklength, int mfm); extern FDI *fdi2raw_header(FILE *f); -extern void fdi2raw_header_free (FDI *); -extern int fdi2raw_get_last_track(FDI *); -extern int fdi2raw_get_num_sector (FDI *); -extern int fdi2raw_get_last_head(FDI *); -extern int fdi2raw_get_type (FDI *); -extern int fdi2raw_get_bit_rate (FDI *); -extern int fdi2raw_get_rotation (FDI *); -extern int fdi2raw_get_write_protect (FDI *); -extern int fdi2raw_get_tpi (FDI *); +extern void fdi2raw_header_free(FDI *); +extern int fdi2raw_get_last_track(FDI *); +extern int fdi2raw_get_num_sector(FDI *); +extern int fdi2raw_get_last_head(FDI *); +extern int fdi2raw_get_type(FDI *); +extern int fdi2raw_get_bit_rate(FDI *); +extern int fdi2raw_get_rotation(FDI *); +extern int fdi2raw_get_write_protect(FDI *); +extern int fdi2raw_get_tpi(FDI *); #ifdef __cplusplus } diff --git a/src/include/tinyglib.h b/src/include/tinyglib.h index 70dae6519..b6cea2989 100644 --- a/src/include/tinyglib.h +++ b/src/include/tinyglib.h @@ -15,101 +15,99 @@ * Copyright 2020 RichardG. */ #ifndef TINYGLIB_H -# define TINYGLIB_H +#define TINYGLIB_H /* Define this to bypass TinyGLib and use full GLib instead. */ #ifdef TINYGLIB_USE_GLIB -#include +# include #else -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> - +# include +# include +# include +# include +# define HAVE_STDARG_H +# include <86box/86box.h> /* Definitions */ -#define G_LITTLE_ENDIAN 1234 -#define G_BIG_ENDIAN 4321 -#define G_PDP_ENDIAN 3412 -#ifdef __BYTE_ORDER__ -# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -# define G_BYTE_ORDER G_LITTLE_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -# define G_BYTE_ORDER G_BIG_ENDIAN -# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ -# define G_BYTE_ORDER G_PDP_ENDIAN -# endif -#endif -#ifndef G_BYTE_ORDER +# define G_LITTLE_ENDIAN 1234 +# define G_BIG_ENDIAN 4321 +# define G_PDP_ENDIAN 3412 +# ifdef __BYTE_ORDER__ +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define G_BYTE_ORDER G_LITTLE_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define G_BYTE_ORDER G_BIG_ENDIAN +# elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ +# define G_BYTE_ORDER G_PDP_ENDIAN +# endif +# endif +# ifndef G_BYTE_ORDER /* Safe to assume LE for MSVC, as Windows is LE on all architectures. */ -# define G_BYTE_ORDER G_LITTLE_ENDIAN -#endif +# define G_BYTE_ORDER G_LITTLE_ENDIAN +# endif -#ifdef _WIN32 -# define G_OS_WIN32 1 -#else -# define G_OS_UNIX 1 -#endif +# ifdef _WIN32 +# define G_OS_WIN32 1 +# else +# define G_OS_UNIX 1 +# endif -#define G_SPAWN_SEARCH_PATH 0 - -#if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) -# define GLIB_SIZEOF_VOID_P 8 -# if defined(__LLP64__) || defined(_WIN64) -# define GLIB_SIZEOF_LONG 4 -# else -# define GLIB_SIZEOF_LONG 8 -# endif -# define GLIB_SIZEOF_SIZE_T 8 -# define GLIB_SIZEOF_SSIZE_T 8 -#else -# define GLIB_SIZEOF_VOID_P 4 -# define GLIB_SIZEOF_LONG 4 -# define GLIB_SIZEOF_SIZE_T 4 -# define GLIB_SIZEOF_SSIZE_T 4 -#endif +# define G_SPAWN_SEARCH_PATH 0 +# if defined(__LP64__) || defined(__LLP64__) || defined(_WIN64) +# define GLIB_SIZEOF_VOID_P 8 +# if defined(__LLP64__) || defined(_WIN64) +# define GLIB_SIZEOF_LONG 4 +# else +# define GLIB_SIZEOF_LONG 8 +# endif +# define GLIB_SIZEOF_SIZE_T 8 +# define GLIB_SIZEOF_SSIZE_T 8 +# else +# define GLIB_SIZEOF_VOID_P 4 +# define GLIB_SIZEOF_LONG 4 +# define GLIB_SIZEOF_SIZE_T 4 +# define GLIB_SIZEOF_SSIZE_T 4 +# endif /* Types */ /* Windows does not define ssize_t, so we need to define it here. */ -#ifndef _SSIZE_T_DEFINED -# define _SSIZE_T_DEFINED -# undef ssize_t -# ifdef _WIN64 -# define ssize_t int64_t -# else -# define ssize_t int32_t -# endif -#endif +# ifndef _SSIZE_T_DEFINED +# define _SSIZE_T_DEFINED +# undef ssize_t +# ifdef _WIN64 +# define ssize_t int64_t +# else +# define ssize_t int32_t +# endif +# endif -#define gboolean int -#define gchar char -#define gint int -#define gint16 int16_t -#define gint32 int32_t -#define gint64 int64_t -#define glong long -#define GPid void * -#define gpointer void * -#define gsize size_t -#define GSpawnFlags void * -#define GSpawnChildSetupFunc void * -#define gssize ssize_t -#define GString char -#define GStrv char ** -#define guint unsigned int -#define guint16 uint16_t -#define guint32 uint32_t -#define guint64 uint64_t +# define gboolean int +# define gchar char +# define gint int +# define gint16 int16_t +# define gint32 int32_t +# define gint64 int64_t +# define glong long +# define GPid void * +# define gpointer void * +# define gsize size_t +# define GSpawnFlags void * +# define GSpawnChildSetupFunc void * +# define gssize ssize_t +# define GString char +# define GStrv char ** +# define guint unsigned int +# define guint16 uint16_t +# define guint32 uint32_t +# define guint64 uint64_t typedef struct _GDebugKey { char key[32]; - int val; + int val; } GDebugKey; typedef struct _GError { @@ -120,80 +118,86 @@ typedef struct _GRand { uint8_t dummy; } GRand; - /* Functions */ -extern gboolean g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, +extern gboolean g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, gchar **envp, GSpawnFlags flags, GSpawnChildSetupFunc child_setup, gpointer user_data, GPid *child_pid, gint stdin_fd, gint stdout_fd, gint stderr_fd, GError **error); -extern GString *g_string_new(gchar *base); -extern gchar *g_string_free(GString *string, gboolean free_segment); -extern gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle); -extern guint g_strv_length(gchar **str_array); - +extern GString *g_string_new(gchar *base); +extern gchar *g_string_free(GString *string, gboolean free_segment); +extern gchar *g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle); +extern guint g_strv_length(gchar **str_array); /* Macros */ -#define tinyglib_pclog(f, s, ...) pclog("TinyGLib " f "(): " s "\n", ##__VA_ARGS__) +# define tinyglib_pclog(f, s, ...) pclog("TinyGLib " f "(): " s "\n", ##__VA_ARGS__) -#define GLIB_CHECK_VERSION(a, b, c) 1 -#ifdef __GNUC__ -# define G_GNUC_PRINTF(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) -#else -# define G_GNUC_PRINTF(format_idx, arg_idx) -#endif -#define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) -#define G_STATIC_ASSERT(e) /* this should probably do something */ -#define G_UNLIKELY(e) (e) - -#define g_assert(e) do { if (!(e)) fatal("TinyGLib g_assert(" #e ")\n"); } while (0) -#ifdef __GNUC__ -# define g_assert_not_reached __builtin_unreachable -#else -# ifdef _MSC_VER -# define g_assert_not_reached() __assume(0) -# else -# define g_assert_not_reached() -# endif -#endif -#define g_critical(s, ...) fatal("TinyGLib g_critical(): " s "\n", ##__VA_ARGS__) -#ifdef TINYGLIB_DEBUG -# define g_debug(s, ...) tinyglib_pclog("g_debug", s, ##__VA_ARGS__) -#else -# define g_debug(s, ...) -#endif -#define g_error(s, ...) tinyglib_pclog("g_error", s, ##__VA_ARGS__) -#define g_error_free(err) -#define g_malloc0(s) calloc(1, s) -#define g_new(t, n) (t *) malloc(sizeof(t) * n) -#define g_new0(t, n) (t *) calloc(n, sizeof(t)) -#ifdef TINYGLIB_DEBUG -# define g_parse_debug_string(s, k, n) ((!!sizeof(k)) * -1) /* unimplemented; always enables all debug flags */ -#else -# define g_parse_debug_string(s, k, n) (!sizeof(k)) -#endif -#define g_rand_int_range(r, min, max) (rand() % (max + 1 - min) + min) -#define g_rand_new() calloc(1, sizeof(GRand)) -#define g_return_val_if_fail(e, v) if (!(e)) return (v) -#define g_shell_parse_argv(a, b, c, d) !!(sizeof(b)) /* unimplemented */ -#define g_strdup(str) ((str) ? strdup(str) : NULL) -#define g_warn_if_fail(e) do { if (!(e)) pclog("TinyGLib g_warn_if_fail(" #e ")\n"); } while (0) -#define g_warn_if_reached() pclog("TinyGLib g_warn_if_reached()\n") -#define g_warning(s, ...) tinyglib_pclog("g_warning", s, ##__VA_ARGS__) +# define GLIB_CHECK_VERSION(a, b, c) 1 +# ifdef __GNUC__ +# define G_GNUC_PRINTF(format_idx, arg_idx) __attribute__((__format__(__printf__, format_idx, arg_idx))) +# else +# define G_GNUC_PRINTF(format_idx, arg_idx) +# endif +# define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) +# define G_STATIC_ASSERT(e) /* this should probably do something */ +# define G_UNLIKELY(e) (e) +# define g_assert(e) \ + do { \ + if (!(e)) \ + fatal("TinyGLib g_assert(" #e ")\n"); \ + } while (0) +# ifdef __GNUC__ +# define g_assert_not_reached __builtin_unreachable +# else +# ifdef _MSC_VER +# define g_assert_not_reached() __assume(0) +# else +# define g_assert_not_reached() +# endif +# endif +# define g_critical(s, ...) fatal("TinyGLib g_critical(): " s "\n", ##__VA_ARGS__) +# ifdef TINYGLIB_DEBUG +# define g_debug(s, ...) tinyglib_pclog("g_debug", s, ##__VA_ARGS__) +# else +# define g_debug(s, ...) +# endif +# define g_error(s, ...) tinyglib_pclog("g_error", s, ##__VA_ARGS__) +# define g_error_free(err) +# define g_malloc0(s) calloc(1, s) +# define g_new(t, n) (t *) malloc(sizeof(t) * n) +# define g_new0(t, n) (t *) calloc(n, sizeof(t)) +# ifdef TINYGLIB_DEBUG +# define g_parse_debug_string(s, k, n) ((!!sizeof(k)) * -1) /* unimplemented; always enables all debug flags */ +# else +# define g_parse_debug_string(s, k, n) (!sizeof(k)) +# endif +# define g_rand_int_range(r, min, max) (rand() % (max + 1 - min) + min) +# define g_rand_new() calloc(1, sizeof(GRand)) +# define g_return_val_if_fail(e, v) \ + if (!(e)) \ + return (v) +# define g_shell_parse_argv(a, b, c, d) !!(sizeof(b)) /* unimplemented */ +# define g_strdup(str) ((str) ? strdup(str) : NULL) +# define g_warn_if_fail(e) \ + do { \ + if (!(e)) \ + pclog("TinyGLib g_warn_if_fail(" #e ")\n"); \ + } while (0) +# define g_warn_if_reached() pclog("TinyGLib g_warn_if_reached()\n") +# define g_warning(s, ...) tinyglib_pclog("g_warning", s, ##__VA_ARGS__) /* Remapped functions */ -#define g_free free -#define g_getenv getenv -#define g_malloc malloc -#define g_rand_free free -#define g_realloc realloc -#define g_snprintf snprintf -#define g_strerror strerror -#define g_strfreev free -#define g_string_append_printf sprintf /* unimplemented */ -#define g_vsnprintf vsnprintf - +# define g_free free +# define g_getenv getenv +# define g_malloc malloc +# define g_rand_free free +# define g_realloc realloc +# define g_snprintf snprintf +# define g_strerror strerror +# define g_strfreev free +# define g_string_append_printf sprintf /* unimplemented */ +# define g_vsnprintf vsnprintf #endif diff --git a/src/lpt.c b/src/lpt.c index 22b9ba30a..b20b25641 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -42,7 +42,7 @@ static const struct { {"plip", &lpt_plip_device }, {"dongle_savquest", &lpt_hasp_savquest_device }, {"", NULL } -// clang-format on + // clang-format on }; char * diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index afd7bb232..5d64bda3b 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -162,10 +162,10 @@ static uint8_t key_queue[16]; static int key_queue_start = 0, key_queue_end = 0; static uint8_t crtc_mask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, - 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, + 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static video_timings_t timing_pc1512 = { VIDEO_BUS, 0, 0, 0, 0, 0, 0 }; /*PC1512 video code handles waitstates itself*/ @@ -2551,7 +2551,7 @@ machine_amstrad_init(const machine_t *model, int type) ms_read, NULL, NULL, ms_write, NULL, NULL, ams); if (mouse_type == MOUSE_TYPE_INTERNAL) { -/* Tell mouse driver about our internal mouse. */ + /* Tell mouse driver about our internal mouse. */ mouse_reset(); mouse_set_buttons(2); mouse_set_poll(ms_poll, ams); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index f55faea58..74e853834 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -702,7 +702,7 @@ const device_config_t compaq_plasma_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t compaq_plasma_device = { diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index a58f9c97d..8f2bec8bd 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -336,26 +336,25 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.BIN", 0x000fe000, 65536, 0); - if (ret) - { + if (ret) { bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F400.BIN", - 0x000f4000, 8192, 0); + 0x000f4000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F600.BIN", - 0x000f6000, 8192, 0); + 0x000f6000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FA00.BIN", - 0x000fa000, 8192, 0); + 0x000fa000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_F800.BIN", - 0x000f8000, 8192, 0); + 0x000f8000, 8192, 0); bios_load_aux_linear("roms/machines/pravetz16/BIOS_IMKO4_FC00.BIN", - 0x000fc000, 8192, 0); + 0x000fc000, 8192, 0); } if (bios_only || !ret) - return ret; + return ret; device_add(&keyboard_pravetz_device); @@ -367,13 +366,13 @@ machine_xt_pravetz16_imko4_init(const machine_t *model) int machine_xt_micoms_xl7turbo_init(const machine_t *model) { - int ret; - + int ret; + ret = bios_load_linear("roms/machines/mxl7t/XL7_TURBO.BIN", - 0x000fe000, 8192, 0); + 0x000fe000, 8192, 0); if (bios_only || !ret) - return ret; + return ret; machine_xt_init_ex(model); return ret; @@ -602,14 +601,14 @@ machine_xt_v20xt_init(const machine_t *model) int ret; ret = bios_load_linear("roms/machines/v20xt/V20XTBios.bin", - 0x000fe000, 8192, 0); + 0x000fe000, 8192, 0); if (bios_only || !ret) - return ret; + return ret; machine_xt_clone_init(model); - return ret; + return ret; } int diff --git a/src/machine/m_xt_olivetti.c b/src/machine/m_xt_olivetti.c index 193015186..d92df9f10 100644 --- a/src/machine/m_xt_olivetti.c +++ b/src/machine/m_xt_olivetti.c @@ -74,43 +74,43 @@ #define CGA_COMPOSITE 1 enum MM58174_ADDR { - /* Registers */ - MM58174_TEST, /* TEST register, write only */ - MM58174_TENTHS, /* Tenths of second, read only */ - MM58174_SECOND1, /* Units of seconds, read only */ - MM58174_SECOND10, /* Tens of seconds, read only */ - MM58174_MINUTE1, - MM58174_MINUTE10, - MM58174_HOUR1, - MM58174_HOUR10, - MM58174_DAY1, - MM58174_DAY10, - MM58174_WEEKDAY, - MM58174_MONTH1, - MM58174_MONTH10, - MM58174_LEAPYEAR, /* Leap year status, write only */ - MM58174_RESET, /* RESET register, write only */ - MM58174_IRQ /* Interrupt register, read / write */ + /* Registers */ + MM58174_TEST, /* TEST register, write only */ + MM58174_TENTHS, /* Tenths of second, read only */ + MM58174_SECOND1, /* Units of seconds, read only */ + MM58174_SECOND10, /* Tens of seconds, read only */ + MM58174_MINUTE1, + MM58174_MINUTE10, + MM58174_HOUR1, + MM58174_HOUR10, + MM58174_DAY1, + MM58174_DAY10, + MM58174_WEEKDAY, + MM58174_MONTH1, + MM58174_MONTH10, + MM58174_LEAPYEAR, /* Leap year status, write only */ + MM58174_RESET, /* RESET register, write only */ + MM58174_IRQ /* Interrupt register, read / write */ }; enum MM58274_ADDR { - /* Registers */ - MM58274_CONTROL, /* Control register */ - MM58274_TENTHS, /* Tenths of second, read only */ - MM58274_SECOND1, - MM58274_SECOND10, - MM58274_MINUTE1, - MM58274_MINUTE10, - MM58274_HOUR1, - MM58274_HOUR10, - MM58274_DAY1, - MM58274_DAY10, - MM58274_MONTH1, - MM58274_MONTH10, - MM58274_YEAR1, - MM58274_YEAR10, - MM58274_WEEKDAY, - MM58274_SETTINGS /* Settings register */ + /* Registers */ + MM58274_CONTROL, /* Control register */ + MM58274_TENTHS, /* Tenths of second, read only */ + MM58274_SECOND1, + MM58274_SECOND10, + MM58274_MINUTE1, + MM58274_MINUTE10, + MM58274_HOUR1, + MM58274_HOUR10, + MM58274_DAY1, + MM58274_DAY10, + MM58274_MONTH1, + MM58274_MONTH10, + MM58274_YEAR1, + MM58274_YEAR10, + MM58274_WEEKDAY, + MM58274_SETTINGS /* Settings register */ }; static struct tm intclk; @@ -124,7 +124,7 @@ typedef struct { uint8_t output_port; uint8_t id; int param, - param_total; + param_total; uint8_t params[16]; uint8_t scan[7]; @@ -254,14 +254,14 @@ mm58174_start(nvr_t *nvr) static void mm58174_write(uint16_t addr, uint8_t val, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; val &= 0x0f; /* Update non-read-only changed values if not synchronizing time to host */ - if ((addr != MM58174_TENTHS) && (addr != MM58174_SECOND1) && (addr != MM58174_SECOND10)) - if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) + if ((addr != MM58174_TENTHS) && (addr != MM58174_SECOND1) && (addr != MM58174_SECOND10)) + if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) nvr_dosave = 1; if ((addr == MM58174_RESET) && (val & 0x01)) { @@ -269,7 +269,7 @@ mm58174_write(uint16_t addr, uint8_t val, void *priv) nvr->regs[MM58174_TENTHS] = 0; if (!(time_sync & TIME_SYNC_ENABLED)) { /* Only set seconds to 0 if not synchronizing time to host clock */ - nvr->regs[MM58174_SECOND1] = 0; + nvr->regs[MM58174_SECOND1] = 0; nvr->regs[MM58174_SECOND10] = 0; } } @@ -285,7 +285,7 @@ mm58174_write(uint16_t addr, uint8_t val, void *priv) static uint8_t mm58174_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; @@ -334,12 +334,12 @@ mm58174_init(nvr_t *nvr, int size) static void mm58274_time_set(uint8_t *regs, struct tm *tm) { - regs[MM58274_SECOND1] = (tm->tm_sec % 10); - regs[MM58274_SECOND10] = (tm->tm_sec / 10); - regs[MM58274_MINUTE1] = (tm->tm_min % 10); - regs[MM58274_MINUTE10] = (tm->tm_min / 10); - regs[MM58274_HOUR1] = (tm->tm_hour % 10); - regs[MM58274_HOUR10] = (tm->tm_hour / 10); + regs[MM58274_SECOND1] = (tm->tm_sec % 10); + regs[MM58274_SECOND10] = (tm->tm_sec / 10); + regs[MM58274_MINUTE1] = (tm->tm_min % 10); + regs[MM58274_MINUTE10] = (tm->tm_min / 10); + regs[MM58274_HOUR1] = (tm->tm_hour % 10); + regs[MM58274_HOUR10] = (tm->tm_hour / 10); /* Store hour in 24-hour or 12-hour mode */ if (regs[MM58274_SETTINGS] & 0x01) { regs[MM58274_HOUR1] = (tm->tm_hour % 10); @@ -352,35 +352,35 @@ mm58274_time_set(uint8_t *regs, struct tm *tm) else regs[MM58274_SETTINGS] &= 0x0B; } - regs[MM58274_WEEKDAY] = (tm->tm_wday + 1); - regs[MM58274_DAY1] = (tm->tm_mday % 10); - regs[MM58274_DAY10] = (tm->tm_mday / 10); - regs[MM58274_MONTH1] = ((tm->tm_mon + 1) % 10); - regs[MM58274_MONTH10] = ((tm->tm_mon + 1) / 10); + regs[MM58274_WEEKDAY] = (tm->tm_wday + 1); + regs[MM58274_DAY1] = (tm->tm_mday % 10); + regs[MM58274_DAY10] = (tm->tm_mday / 10); + regs[MM58274_MONTH1] = ((tm->tm_mon + 1) % 10); + regs[MM58274_MONTH10] = ((tm->tm_mon + 1) / 10); /* MM58274 can store 00 to 99 years but M240 uses the YEAR1 register to count 8 years from leap year */ - regs[MM58274_YEAR1] = ((tm->tm_year + 1900) % 8); + regs[MM58274_YEAR1] = ((tm->tm_year + 1900) % 8); /* Keep bit 0 and 1 12-hour / 24-hour and AM / PM */ - regs[MM58274_SETTINGS] &= 0x03; + regs[MM58274_SETTINGS] &= 0x03; /* Set leap counter bits 2 and 3 */ - regs[MM58274_SETTINGS] += (4* (regs[MM58274_YEAR1] & 0x03)); + regs[MM58274_SETTINGS] += (4 * (regs[MM58274_YEAR1] & 0x03)); } /* Get the chip time. */ static void mm58274_time_get(uint8_t *regs, struct tm *tm) { - tm->tm_sec = nibbles(MM58274_SECOND); - tm->tm_min = nibbles(MM58274_MINUTE); + tm->tm_sec = nibbles(MM58274_SECOND); + tm->tm_min = nibbles(MM58274_MINUTE); /* Read hour in 24-hour or 12-hour mode */ if (regs[MM58274_SETTINGS] & 0x01) tm->tm_hour = nibbles(MM58274_HOUR); else tm->tm_hour = ((nibbles(MM58274_HOUR) % 12) + (regs[MM58274_SETTINGS] & 0x04) ? 12 : 0); - tm->tm_wday = (regs[MM58274_WEEKDAY] - 1); - tm->tm_mday = nibbles(MM58274_DAY); - tm->tm_mon = (nibbles(MM58274_MONTH) - 1); + tm->tm_wday = (regs[MM58274_WEEKDAY] - 1); + tm->tm_mday = nibbles(MM58274_DAY); + tm->tm_mon = (nibbles(MM58274_MONTH) - 1); /* MM58274 can store 00 to 99 years but M240 uses the YEAR1 register to count 8 years from leap year */ - tm->tm_year = (1984 + regs[MM58274_YEAR1] - 1900); + tm->tm_year = (1984 + regs[MM58274_YEAR1] - 1900); } /* This is called every second through the NVR/RTC hook. */ @@ -413,14 +413,14 @@ mm58274_start(nvr_t *nvr) static void mm58274_write(uint16_t addr, uint8_t val, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; val &= 0x0f; /* Update non-read-only changed values if not synchronizing time to host */ if ((addr != MM58274_TENTHS)) - if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) + if ((nvr->regs[addr] != val) && !(time_sync & TIME_SYNC_ENABLED)) nvr_dosave = 1; if ((addr == MM58274_CONTROL) && (val & 0x04)) { @@ -439,7 +439,7 @@ mm58274_write(uint16_t addr, uint8_t val, void *priv) static uint8_t mm58274_read(uint16_t addr, void *priv) { - nvr_t *nvr = (nvr_t *) priv; + nvr_t *nvr = (nvr_t *) priv; addr &= 0x0f; @@ -517,7 +517,7 @@ m24_kbd_adddata_ex(uint16_t val) kbd_adddata_process(val, m24_kbd_adddata); } -/* +/* From the Olivetti M21/M24 Theory of Operation: Port Function @@ -535,7 +535,7 @@ static void m24_kbd_write(uint16_t port, uint8_t val, void *priv) { m24_kbd_t *m24_kbd = (m24_kbd_t *) priv; - uint8_t ret; + uint8_t ret; xt_olivetti_log("M24: write %04X %02X\n", port, val); @@ -1831,7 +1831,7 @@ machine_xt_m24_init(const machine_t *model) int machine_xt_m240_init(const machine_t *model) { - int ret; + int ret; m24_kbd_t *m24_kbd; nvr_t *nvr; diff --git a/src/machine/m_xt_t1000_vid.c b/src/machine/m_xt_t1000_vid.c index 40110ce47..60fb59082 100644 --- a/src/machine/m_xt_t1000_vid.c +++ b/src/machine/m_xt_t1000_vid.c @@ -723,7 +723,7 @@ static const device_config_t t1000_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t t1000_video_device = { diff --git a/src/machine/m_xt_xi8088.c b/src/machine/m_xt_xi8088.c index c27631869..5bf958d8a 100644 --- a/src/machine/m_xt_xi8088.c +++ b/src/machine/m_xt_xi8088.c @@ -156,7 +156,7 @@ static const device_config_t xi8088_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t xi8088_device = { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index b0a087336..06b00dbef 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11969,8 +11969,8 @@ const machine_t machines[] = { /* Saved copies - jumpers get applied to these. We use also machine_gpio to store IBM PC/XT jumpers as they need more than one byte. */ -static uint16_t machine_p1; -static uint32_t machine_gpio; +static uint16_t machine_p1; +static uint32_t machine_gpio; uint8_t machine_get_p1(void) @@ -12005,97 +12005,97 @@ machine_set_gpio(uint32_t gpio) int machine_count(void) { - return((sizeof(machines) / sizeof(machine_t)) - 1); + return ((sizeof(machines) / sizeof(machine_t)) - 1); } char * machine_getname(void) { - return((char *)machines[machine].name); + return ((char *) machines[machine].name); } char * machine_getname_ex(int m) { - return((char *)machines[m].name); + return ((char *) machines[m].name); } const device_t * machine_getdevice(int m) { if (machines[m].device) - return(machines[m].device); + return (machines[m].device); - return(NULL); + return (NULL); } const device_t * machine_getviddevice(int m) { if (machines[m].vid_device) - return(machines[m].vid_device); + return (machines[m].vid_device); - return(NULL); + return (NULL); } const device_t * machine_getsnddevice(int m) { if (machines[m].snd_device) - return(machines[m].snd_device); + return (machines[m].snd_device); - return(NULL); + return (NULL); } const device_t * machine_getnetdevice(int m) { if (machines[m].net_device) - return(machines[m].net_device); + return (machines[m].net_device); - return(NULL); + return (NULL); } char * machine_get_internal_name(void) { - return((char *)machines[machine].internal_name); + return ((char *) machines[machine].internal_name); } char * machine_get_internal_name_ex(int m) { - return((char *)machines[m].internal_name); + return ((char *) machines[m].internal_name); } int machine_get_nvrmask(int m) { - return(machines[m].nvrmask); + return (machines[m].nvrmask); } int machine_has_flags(int m, int flags) { - return(machines[m].flags & flags); + return (machines[m].flags & flags); } int machine_has_bus(int m, int bus_flags) { - return(machines[m].bus_flags & bus_flags); + return (machines[m].bus_flags & bus_flags); } int machine_has_cartridge(int m) { - return(machine_has_bus(m, MACHINE_CARTRIDGE) ? 1 : 0); + return (machine_has_bus(m, MACHINE_CARTRIDGE) ? 1 : 0); } int machine_get_min_ram(int m) { - return(machines[m].ram.min); + return (machines[m].ram.min); } int @@ -12111,13 +12111,13 @@ machine_get_max_ram(int m) int machine_get_ram_granularity(int m) { - return(machines[m].ram.step); + return (machines[m].ram.step); } int machine_get_type(int m) { - return(machines[m].type); + return (machines[m].type); } int @@ -12126,16 +12126,16 @@ machine_get_machine_from_internal_name(char *s) int c = 0; while (machines[c].init != NULL) { - if (!strcmp(machines[c].internal_name, (const char *)s)) - return(c); + if (!strcmp(machines[c].internal_name, (const char *) s)) + return (c); c++; } - return(0); + return (0); } int machine_has_mouse(void) { - return(machines[machine].flags & MACHINE_MOUSE); + return (machines[machine].flags & MACHINE_MOUSE); } diff --git a/src/mem/mem.c b/src/mem/mem.c index e0456bf5c..4d5a5238b 100644 --- a/src/mem/mem.c +++ b/src/mem/mem.c @@ -55,12 +55,12 @@ #endif mem_mapping_t ram_low_mapping, /* 0..640K mapping */ - ram_mid_mapping, /* 640..1024K mapping */ - ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */ - ram_remapped_mapping, /* 640..1024K mapping */ - ram_remapped_mapping2,/* 640..1024K second mapping, for SiS 471 mode */ - ram_high_mapping, /* 1024K+ mapping */ - ram_2gb_mapping, /* 1024M+ mapping */ + ram_mid_mapping, /* 640..1024K mapping */ + ram_mid_mapping2, /* 640..1024K mapping, second part, for SiS 471 in relocate mode */ + ram_remapped_mapping, /* 640..1024K mapping */ + ram_remapped_mapping2, /* 640..1024K second mapping, for SiS 471 mode */ + ram_high_mapping, /* 1024K+ mapping */ + ram_2gb_mapping, /* 1024M+ mapping */ ram_split_mapping, bios_mapping, bios_high_mapping; @@ -2806,9 +2806,9 @@ mem_remap_top(int kb) uint32_t c; uint32_t start = (mem_size >= 1024) ? mem_size : 1024; int offset, size = mem_size - 640; - int set = 1; - static int old_kb = 0; - int sis_mode = 0; + int set = 1; + static int old_kb = 0; + int sis_mode = 0; uint32_t start_addr = 0, addr = 0; mem_log("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); @@ -2817,7 +2817,7 @@ mem_remap_top(int kb) /* SiS 471 special mode. */ if (kb == -256) { - kb = 256; + kb = 256; sis_mode = 1; } @@ -2830,11 +2830,11 @@ mem_remap_top(int kb) if (size > kb) size = kb; - remap_start_addr = start << 10; + remap_start_addr = start << 10; remap_start_addr2 = (start << 10) + 0x00020000; for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) { - offset = c - ((start * 1024) >> 12); + offset = c - ((start * 1024) >> 12); /* Use A0000-BFFFF, D0000-EFFFF instead of C0000-DFFFF, E0000-FFFFF. */ addr = 0xa0000 + (offset << 12); if (sis_mode) { @@ -2858,8 +2858,8 @@ mem_remap_top(int kb) mem_set_mem_state_both(start * 1024, size * 1024, set ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); for (c = 0xa0; c < 0xf0; c++) { - if ((c >= 0xc0) && (c <= 0xcf)) - continue; + if ((c >= 0xc0) && (c <= 0xcf)) + continue; if (sis_mode || ((c << 12) >= (mem_size << 10))) pages[c].mem = page_ff; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index ff2a28887..d3c5e29b5 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -756,11 +756,11 @@ padr_match(nic_t *dev, const uint8_t *buf, int size) result = !CSR_DRCVPA(dev) && !memcmp(hdr->ether_dhost, padr, 6); pcnet_log(3, "%s: packet dhost=%02x:%02x:%02x:%02x:%02x:%02x, " - "padr=%02x:%02x:%02x:%02x:%02x:%02x => %d\n", - dev->name, - hdr->ether_dhost[0], hdr->ether_dhost[1], hdr->ether_dhost[2], - hdr->ether_dhost[3], hdr->ether_dhost[4], hdr->ether_dhost[5], - padr[0], padr[1], padr[2], padr[3], padr[4], padr[5], result); + "padr=%02x:%02x:%02x:%02x:%02x:%02x => %d\n", + dev->name, + hdr->ether_dhost[0], hdr->ether_dhost[1], hdr->ether_dhost[2], + hdr->ether_dhost[3], hdr->ether_dhost[4], hdr->ether_dhost[5], + padr[0], padr[1], padr[2], padr[3], padr[4], padr[5], result); return result; } @@ -944,13 +944,13 @@ pcnetInit(nic_t *dev) dev->GCUpperPhys = 0; PCNET_INIT(); pcnet_log(3, "%s: initblk.rlen=%#04x, initblk.tlen=%#04x\n", - dev->name, initblk.rlen, initblk.tlen); + dev->name, initblk.rlen, initblk.tlen); } else { struct INITBLK16 initblk; dev->GCUpperPhys = (0xff00 & (uint32_t) dev->aCSR[2]) << 16; PCNET_INIT(); pcnet_log(3, "%s: initblk.rlen=%#04x, initblk.tlen=%#04x\n", - dev->name, initblk.rlen, initblk.tlen); + dev->name, initblk.rlen, initblk.tlen); } #undef PCNET_INIT @@ -985,9 +985,9 @@ pcnetInit(nic_t *dev) CSR_CXST(dev) = CSR_CXBC(dev) = CSR_NXST(dev) = CSR_NXBC(dev) = 0; pcnet_log(1, "%s: Init: SWSTYLE=%d GCRDRA=%#010x[%d] GCTDRA=%#010x[%d]%s\n", - dev->name, BCR_SWSTYLE(dev), - dev->GCRDRA, CSR_RCVRL(dev), dev->GCTDRA, CSR_XMTRL(dev), - !dev->fSignalRxMiss ? " (CSR0_MISS disabled)" : ""); + dev->name, BCR_SWSTYLE(dev), + dev->GCRDRA, CSR_RCVRL(dev), dev->GCTDRA, CSR_XMTRL(dev), + !dev->fSignalRxMiss ? " (CSR0_MISS disabled)" : ""); if (dev->GCRDRA & (dev->iLog2DescSize - 1)) pcnet_log(1, "%s: Warning: Misaligned RDRA\n", dev->name); @@ -1072,7 +1072,7 @@ pcnetRdtePoll(nic_t *dev) */ if (++dev->uCntBadRMD < 50) pcnet_log(1, "%s: BAD RMD ENTRIES AT %#010x (i=%d)\n", - dev->name, addr, i); + dev->name, addr, i); return; } @@ -1098,7 +1098,7 @@ pcnetRdtePoll(nic_t *dev) */ if (++dev->uCntBadRMD < 50) pcnet_log(1, "%s: BAD RMD ENTRIES + AT %#010x (i=%d)\n", - dev->name, addr, i); + dev->name, addr, i); return; } @@ -1126,7 +1126,7 @@ pcnetTdtePoll(nic_t *dev, TMD *tmd) if (tmd->tmd1.ones != 15) { pcnet_log(1, "%s: BAD TMD XDA=%#010x\n", - dev->name, PHYSADDR(dev, cxda)); + dev->name, PHYSADDR(dev, cxda)); return 0; } @@ -1182,7 +1182,7 @@ pcnetCalcPacketLen(nic_t *dev, int cb) } if (tmd.tmd1.ones != 15) { pcnet_log(1, "%s: BAD TMD XDA=%#010x\n", - dev->name, PHYSADDR(dev, addrDesc)); + dev->name, PHYSADDR(dev, addrDesc)); pcnet_log(3, "%s: pcnetCalcPacketLen: bad TMD, return %u\n", dev->name, cbPacket); return cbPacket; } @@ -1228,9 +1228,9 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) return 0; pcnet_log(1, "%s: pcnetReceiveNoSync: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name, - buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], - size); + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + size); /* * Perform address matching. @@ -1411,7 +1411,7 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) dev->aCSR[0] |= 0x0400; pcnet_log(1, "%s: RINT set, RCVRC=%d CRDA=%#010x\n", dev->name, - CSR_RCVRC(dev), PHYSADDR(dev, CSR_CRDA(dev))); + CSR_RCVRC(dev), PHYSADDR(dev, CSR_CRDA(dev))); /* guest driver is owner: force repoll of current and next RDTEs */ CSR_CRST(dev) = 0; @@ -1574,7 +1574,7 @@ pcnetAsyncTransmit(nic_t *dev) CSR_XMTRC(dev) = CSR_XMTRL(dev); else CSR_XMTRC(dev) - --; + --; TMD dummy; if (!pcnetTdtePoll(dev, &dummy)) { @@ -1629,7 +1629,7 @@ pcnetAsyncTransmit(nic_t *dev) CSR_XMTRC(dev) = CSR_XMTRL(dev); else CSR_XMTRC(dev) - --; + --; break; } } /* the loop */ @@ -1897,7 +1897,7 @@ pcnet_csr_writew(nic_t *dev, uint16_t rap, uint16_t val) return; } pcnet_log(3, "%s: WRITE CSR%d, %#06x (hacked %#06x) (alt init)\n", dev->name, - rap, val, 1 + ~val); + rap, val, 1 + ~val); val = 1 + ~val; /* @@ -2984,12 +2984,12 @@ pcnet_init(const device_t *info) } pcnet_log(2, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", - dev->name, dev->base_address, dev->base_irq, - dev->aPROM[0], dev->aPROM[1], dev->aPROM[2], - dev->aPROM[3], dev->aPROM[4], dev->aPROM[5]); + dev->name, dev->base_address, dev->base_irq, + dev->aPROM[0], dev->aPROM[1], dev->aPROM[2], + dev->aPROM[3], dev->aPROM[4], dev->aPROM[5]); pcnet_log(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, - dev->is_pci ? "PCI" : "VLB/ISA", dev->base_address, dev->base_irq); + dev->is_pci ? "PCI" : "VLB/ISA", dev->base_address, dev->base_irq); /* Reset the board. */ pcnetHardReset(dev); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 1a9c00212..35dfb52bb 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -38,7 +38,7 @@ #include <86box/config.h> #include <86box/video.h> -# define _SSIZE_T_DEFINED +#define _SSIZE_T_DEFINED #include #ifdef _WIN32 diff --git a/src/network/network.c b/src/network/network.c index 38c480b6c..0fc137092 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -55,7 +55,7 @@ #include #include #ifndef _WIN32 -#include +# include #endif /* _WIN32 */ #include #define HAVE_STDARG_H @@ -126,7 +126,7 @@ netdev_t network_devs[NET_HOST_INTF_MAX]; /* Local variables. */ -#if defined ENABLE_NETWORK_LOG && !defined(_WIN32) +#if defined ENABLE_NETWORK_LOG && !defined(_WIN32) int network_do_log = ENABLE_NETWORK_LOG; static FILE *network_dump = NULL; static mutex_t *network_dump_mutex; diff --git a/src/network/pcap_if.c b/src/network/pcap_if.c index 53eb6804a..69110cb34 100644 --- a/src/network/pcap_if.c +++ b/src/network/pcap_if.c @@ -288,7 +288,7 @@ main(int argc, char **argv) return (1); } -/* Looks good, go and listen.. */ + /* Looks good, go and listen.. */ i = start_cap(interfaces[i - 1].device); dynld_close(pcap_handle); diff --git a/src/network/slirp/tinyglib.c b/src/network/slirp/tinyglib.c index 9504ff3af..702c39ad7 100644 --- a/src/network/slirp/tinyglib.c +++ b/src/network/slirp/tinyglib.c @@ -28,18 +28,16 @@ g_spawn_async_with_fds(const gchar *working_directory, gchar **argv, return 0; } - /* Needs bounds checking, but not really used by libslirp. */ GString * g_string_new(gchar *base) { char *ret = malloc(4096); if (base) - strcpy(ret, base); + strcpy(ret, base); return ret; } - /* Unimplemented, as with anything related to GString. */ gchar * g_string_free(GString *string, gboolean free_segment) @@ -47,87 +45,84 @@ g_string_free(GString *string, gboolean free_segment) return (free_segment ? NULL : string); } - /* Implementation borrowed from GLib itself. */ gchar * g_strstr_len(const gchar *haystack, gssize haystack_len, const gchar *needle) { if (haystack_len < 0) - return strstr(haystack, needle); + return strstr(haystack, needle); else { - const gchar *p = haystack; - gsize needle_len = strlen(needle); - gsize haystack_len_unsigned = haystack_len; - const gchar *end; - gsize i; + const gchar *p = haystack; + gsize needle_len = strlen(needle); + gsize haystack_len_unsigned = haystack_len; + const gchar *end; + gsize i; - if (needle_len == 0) - return (gchar *) haystack; + if (needle_len == 0) + return (gchar *) haystack; - if (haystack_len_unsigned < needle_len) - return NULL; + if (haystack_len_unsigned < needle_len) + return NULL; - end = haystack + haystack_len - needle_len; + end = haystack + haystack_len - needle_len; - while (p <= end && *p) { - for (i = 0; i < needle_len; i++) - if (p[i] != needle[i]) - goto next; + while (p <= end && *p) { + for (i = 0; i < needle_len; i++) + if (p[i] != needle[i]) + goto next; - return (gchar *)p; + return (gchar *) p; next: - p++; - } + p++; + } - return NULL; + return NULL; } } - /* Implementation borrowed from GLib itself. */ guint g_strv_length(gchar **str_array) { guint i = 0; while (str_array[i] != NULL) - ++i; + ++i; return i; } /* Implementation borrowed from GLib itself. */ gsize -g_strlcpy (gchar *dest, - const gchar *src, - gsize dest_size) +g_strlcpy(gchar *dest, + const gchar *src, + gsize dest_size) { - gchar *d = dest; - const gchar *s = src; - gsize n = dest_size; + gchar *d = dest; + const gchar *s = src; + gsize n = dest_size; - if (dest == NULL) return 0; - if (src == NULL) return 0; + if (dest == NULL) + return 0; + if (src == NULL) + return 0; - /* Copy as many bytes as will fit */ - if (n != 0 && --n != 0) - do - { - gchar c = *s++; + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) + do { + gchar c = *s++; - *d++ = c; - if (c == 0) - break; - } - while (--n != 0); + *d++ = c; + if (c == 0) + break; + } while (--n != 0); - /* If not enough room in dest, add NUL and traverse rest of src */ - if (n == 0) - { - if (dest_size != 0) - *d = 0; - while (*s++) - ; + /* If not enough room in dest, add NUL and traverse rest of src */ + if (n == 0) { + if (dest_size != 0) + *d = 0; + while (*s++) + ; } - return s - src - 1; /* count does not include NUL */ + return s - src - 1; /* count does not include NUL */ } diff --git a/src/pci.c b/src/pci.c index f8119a55e..7b4464407 100644 --- a/src/pci.c +++ b/src/pci.c @@ -404,9 +404,9 @@ pci_set_pmc(uint8_t pmc) io_sethandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_sethandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfc, 4, - pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); } else if (pci_pmc && !(pmc & 0x01)) { io_removehandler(pci_base, pci_size, pci_type2_read, NULL, NULL, @@ -420,9 +420,9 @@ pci_set_pmc(uint8_t pmc) io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfc, 4, - pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, @@ -509,7 +509,7 @@ static uint8_t pci_type2_read(uint16_t port, void *priv) { uint8_t slot = 0; - uint8_t ret = 0xff; + uint8_t ret = 0xff; if (port == 0xcf8) ret = pci_key | (pci_func << 1); @@ -862,11 +862,11 @@ pci_reset(void) io_removehandler(0x0cf8, 1, NULL, NULL, pci_cf8_read, NULL, NULL, pci_cf8_write, NULL); io_removehandler(0x0cfc, 4, - pci_read,pci_readw,pci_readl, pci_write,pci_writew,pci_writel, NULL); + pci_read, pci_readw, pci_readl, pci_write, pci_writew, pci_writel, NULL); io_removehandler(0x0cf8, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_removehandler(0x0cfa, 1, - pci_type2_read,NULL,NULL, pci_type2_write,NULL,NULL, NULL); + pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cf8, 1, pci_type2_read, NULL, NULL, pci_type2_write, NULL, NULL, NULL); io_sethandler(0x0cfa, 1, diff --git a/src/printer/png.c b/src/printer/png.c index 56e2ccfc7..bb862a953 100644 --- a/src/printer/png.c +++ b/src/printer/png.c @@ -124,7 +124,7 @@ error: png_log("PNG: fatal error, bailing out, error = %i\n", errno); if (png != NULL) PNGFUNC(destroy_write_struct) - (&png, &info); + (&png, &info); if (fp != NULL) (void) fclose(fp); return (0); @@ -206,7 +206,7 @@ png_write_rgb(char *fn, uint8_t *pix, int16_t w, int16_t h, uint16_t pitch, PALE error: if (png != NULL) PNGFUNC(destroy_write_struct) - (&png, &info); + (&png, &info); if (fp != NULL) (void) fclose(fp); return; diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 2d439e277..0de04926d 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -350,7 +350,7 @@ ps_init(void *lpt) } } -/* Cache print folder path. */ + /* Cache print folder path. */ memset(dev->printer_path, 0x00, sizeof(dev->printer_path)); path_append_filename(dev->printer_path, usr_path, "printer"); if (!plat_dir_check(dev->printer_path)) diff --git a/src/qt/cocoa_mouse.hpp b/src/qt/cocoa_mouse.hpp index 8db79d9e8..af78abad6 100644 --- a/src/qt/cocoa_mouse.hpp +++ b/src/qt/cocoa_mouse.hpp @@ -2,13 +2,12 @@ #include #if QT_VERSION_MAJOR >= 6 -#define result_t qintptr +# define result_t qintptr #else -#define result_t long +# define result_t long #endif -class CocoaEventFilter : public QAbstractNativeEventFilter -{ +class CocoaEventFilter : public QAbstractNativeEventFilter { public: CocoaEventFilter() {}; ~CocoaEventFilter(); diff --git a/src/qt/evdev_mouse.cpp b/src/qt/evdev_mouse.cpp index 5ad252f1a..c3d926285 100644 --- a/src/qt/evdev_mouse.cpp +++ b/src/qt/evdev_mouse.cpp @@ -26,63 +26,59 @@ #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/mouse.h> #include } -static std::vector> evdev_mice; -static std::atomic stopped = false; -static QThread* evdev_thread; +static std::vector> evdev_mice; +static std::atomic stopped = false; +static QThread *evdev_thread; static std::atomic evdev_mouse_rel_x = 0, evdev_mouse_rel_y = 0; -void evdev_mouse_poll() +void +evdev_mouse_poll() { - if (!evdev_mice.size() || !mouse_capture) - { + if (!evdev_mice.size() || !mouse_capture) { evdev_mouse_rel_x = 0; evdev_mouse_rel_y = 0; return; } - mouse_x = evdev_mouse_rel_x; - mouse_y = evdev_mouse_rel_y; + mouse_x = evdev_mouse_rel_x; + mouse_y = evdev_mouse_rel_y; evdev_mouse_rel_x = evdev_mouse_rel_y = 0; } -void evdev_thread_func() +void +evdev_thread_func() { - struct pollfd *pfds = (struct pollfd*)calloc(evdev_mice.size(), sizeof(struct pollfd)); - for (unsigned int i = 0; i < evdev_mice.size(); i++) - { - pfds[i].fd = libevdev_get_fd(evdev_mice[i].second); + struct pollfd *pfds = (struct pollfd *) calloc(evdev_mice.size(), sizeof(struct pollfd)); + for (unsigned int i = 0; i < evdev_mice.size(); i++) { + pfds[i].fd = libevdev_get_fd(evdev_mice[i].second); pfds[i].events = POLLIN; } - while (!stopped) - { + while (!stopped) { poll(pfds, evdev_mice.size(), 500); - for (unsigned int i = 0; i < evdev_mice.size(); i++) - { + for (unsigned int i = 0; i < evdev_mice.size(); i++) { struct input_event ev; if (pfds[i].revents & POLLIN) { - while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) - { - if (ev.type == EV_REL && mouse_capture) - { - if (ev.code == REL_X) evdev_mouse_rel_x += ev.value; - if (ev.code == REL_Y) evdev_mouse_rel_y += ev.value; + while (libevdev_next_event(evdev_mice[i].second, LIBEVDEV_READ_FLAG_NORMAL, &ev) == 0) { + if (ev.type == EV_REL && mouse_capture) { + if (ev.code == REL_X) + evdev_mouse_rel_x += ev.value; + if (ev.code == REL_Y) + evdev_mouse_rel_y += ev.value; } } } } } - for (unsigned int i = 0; i < evdev_mice.size(); i++) - { + for (unsigned int i = 0; i < evdev_mice.size(); i++) { libevdev_free(evdev_mice[i].second); evdev_mice[i].second = nullptr; close(evdev_mice[i].first); @@ -91,7 +87,8 @@ void evdev_thread_func() evdev_mice.clear(); } -void evdev_stop() +void +evdev_stop() { if (evdev_thread) { stopped = true; @@ -100,37 +97,32 @@ void evdev_stop() } } -void evdev_init() +void +evdev_init() { - if (evdev_thread) return; - for (int i = 0; i < 256; i++) - { + if (evdev_thread) + return; + for (int i = 0; i < 256; i++) { std::string evdev_device_path = "/dev/input/event" + std::to_string(i); - int fd = open(evdev_device_path.c_str(), O_NONBLOCK | O_RDONLY); - if (fd != -1) - { - libevdev* input_struct = nullptr; - int rc = libevdev_new_from_fd(fd, &input_struct); - if (rc <= -1) - { + int fd = open(evdev_device_path.c_str(), O_NONBLOCK | O_RDONLY); + if (fd != -1) { + libevdev *input_struct = nullptr; + int rc = libevdev_new_from_fd(fd, &input_struct); + if (rc <= -1) { close(fd); continue; - } - else - { - if (!libevdev_has_event_type(input_struct, EV_REL) || !libevdev_has_event_code(input_struct, EV_KEY, BTN_LEFT)) - { + } else { + if (!libevdev_has_event_type(input_struct, EV_REL) || !libevdev_has_event_code(input_struct, EV_KEY, BTN_LEFT)) { libevdev_free(input_struct); close(fd); continue; } evdev_mice.push_back(std::make_pair(fd, input_struct)); } - } - else if (errno == ENOENT) break; + } else if (errno == ENOENT) + break; } - if (evdev_mice.size() != 0) - { + if (evdev_mice.size() != 0) { evdev_thread = QThread::create(evdev_thread_func); evdev_thread->start(); atexit(evdev_stop); diff --git a/src/qt/macos_event_filter.mm b/src/qt/macos_event_filter.mm index 0ea799f99..6f84beee5 100644 --- a/src/qt/macos_event_filter.mm +++ b/src/qt/macos_event_filter.mm @@ -1,25 +1,23 @@ #include -//#include "86box/plat.h" +// #include "86box/plat.h" #include "cocoa_mouse.hpp" #import -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/keyboard.h> #include <86box/mouse.h> #include <86box/config.h> -//#include <86box/plat.h> +// #include <86box/plat.h> #include <86box/plat_dynld.h> #include <86box/device.h> #include <86box/timer.h> #include <86box/ui.h> #include <86box/video.h> -extern int mouse_capture; +extern int mouse_capture; extern void plat_mouse_capture(int); } -typedef struct mouseinputdata -{ +typedef struct mouseinputdata { int deltax, deltay, deltaz; int mousebuttons; } mouseinputdata; @@ -28,64 +26,63 @@ static mouseinputdata mousedata; CocoaEventFilter::~CocoaEventFilter() { - } -bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +bool +CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { - if (mouse_capture) - { - if (eventType == "mac_generic_NSEvent") - { - NSEvent* event = (NSEvent*)message; + if (mouse_capture) { + if (eventType == "mac_generic_NSEvent") { + NSEvent *event = (NSEvent *) message; if ([event type] == NSEventTypeMouseMoved || [event type] == NSEventTypeLeftMouseDragged || [event type] == NSEventTypeRightMouseDragged - || [event type] == NSEventTypeOtherMouseDragged) - { + || [event type] == NSEventTypeOtherMouseDragged) { mousedata.deltax += [event deltaX]; mousedata.deltay += [event deltaY]; return true; } - if ([event type] == NSEventTypeScrollWheel) - { + if ([event type] == NSEventTypeScrollWheel) { mousedata.deltaz += [event deltaY]; return true; } - switch ([event type]) - { - default: return false; + switch ([event type]) { + default: + return false; case NSEventTypeLeftMouseDown: - { - mousedata.mousebuttons |= 1; - break; - } + { + mousedata.mousebuttons |= 1; + break; + } case NSEventTypeLeftMouseUp: - { - mousedata.mousebuttons &= ~1; - break; - } + { + mousedata.mousebuttons &= ~1; + break; + } case NSEventTypeRightMouseDown: - { - mousedata.mousebuttons |= 2; - break; - } + { + mousedata.mousebuttons |= 2; + break; + } case NSEventTypeRightMouseUp: - { - mousedata.mousebuttons &= ~2; - break; - } + { + mousedata.mousebuttons &= ~2; + break; + } case NSEventTypeOtherMouseDown: - { - mousedata.mousebuttons |= 4; - break; - } + { + mousedata.mousebuttons |= 4; + break; + } case NSEventTypeOtherMouseUp: - { - if (mouse_get_buttons() < 3) { plat_mouse_capture(0); return true; } - mousedata.mousebuttons &= ~4; - break; - } + { + if (mouse_get_buttons() < 3) { + plat_mouse_capture(0); + return true; + } + mousedata.mousebuttons &= ~4; + break; + } } return true; } @@ -93,11 +90,12 @@ bool CocoaEventFilter::nativeEventFilter(const QByteArray &eventType, void *mess return false; } -extern "C" void macos_poll_mouse() +extern "C" void +macos_poll_mouse() { - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; } diff --git a/src/qt/qt.c b/src/qt/qt.c index bb6d9658d..f1c6eee3f 100644 --- a/src/qt/qt.c +++ b/src/qt/qt.c @@ -17,7 +17,7 @@ * implemented in Qt */ #if !defined(_WIN32) || !defined(__clang__) -#include +# include #endif #include #include @@ -29,14 +29,17 @@ #include <86box/timer.h> #include <86box/nvr.h> -int qt_nvr_save(void) { +int +qt_nvr_save(void) +{ return nvr_save(); } -char icon_set[256] = ""; /* name of the iconset to be used */ +char icon_set[256] = ""; /* name of the iconset to be used */ int -plat_vidapi(char* api) { +plat_vidapi(char *api) +{ if (!strcasecmp(api, "default") || !strcasecmp(api, "system")) { return 0; } else if (!strcasecmp(api, "qt_software")) { @@ -58,34 +61,36 @@ plat_vidapi(char* api) { return 0; } -char* plat_vidapi_name(int api) { - char* name = "default"; +char * +plat_vidapi_name(int api) +{ + char *name = "default"; switch (api) { - case 0: - name = "qt_software"; - break; - case 1: - name = "qt_opengl"; - break; - case 2: - name = "qt_opengles"; - break; - case 3: - name = "qt_opengl3"; - break; - case 4: - name = "qt_vulkan"; - break; - case 5: - name = "qt_d3d9"; - break; - case 6: - name = "vnc"; - break; - default: - fatal("Unknown renderer: %i\n", api); - break; + case 0: + name = "qt_software"; + break; + case 1: + name = "qt_opengl"; + break; + case 2: + name = "qt_opengles"; + break; + case 3: + name = "qt_opengl3"; + break; + case 4: + name = "qt_vulkan"; + break; + case 5: + name = "qt_d3d9"; + break; + case 6: + name = "vnc"; + break; + default: + fatal("Unknown renderer: %i\n", api); + break; } return name; diff --git a/src/qt/qt_cdrom.c b/src/qt/qt_cdrom.c index a15e9c600..d0ab0113e 100644 --- a/src/qt/qt_cdrom.c +++ b/src/qt/qt_cdrom.c @@ -45,11 +45,11 @@ plat_cdrom_ui_update(uint8_t id, uint8_t reload) cdrom_t *drv = &cdrom[id]; if (drv->host_drive == 0) { - ui_sb_update_icon_state(SB_CDROM|id, 1); + ui_sb_update_icon_state(SB_CDROM | id, 1); } else { - ui_sb_update_icon_state(SB_CDROM|id, 0); + ui_sb_update_icon_state(SB_CDROM | id, 0); } - //media_menu_update_cdrom(id); - ui_sb_update_tip(SB_CDROM|id); + // media_menu_update_cdrom(id); + ui_sb_update_tip(SB_CDROM | id); } diff --git a/src/qt/qt_d3d9renderer.cpp b/src/qt/qt_d3d9renderer.cpp index b4269d2e7..fed8e72b3 100644 --- a/src/qt/qt_d3d9renderer.cpp +++ b/src/qt/qt_d3d9renderer.cpp @@ -3,14 +3,14 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/video.h> } D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) - : QWidget{parent}, RendererCommon() + : QWidget { parent } + , RendererCommon() { QPalette pal = palette(); pal.setColor(QPalette::Window, Qt::black); @@ -22,7 +22,7 @@ D3D9Renderer::D3D9Renderer(QWidget *parent, int monitor_index) setAttribute(Qt::WA_NoSystemBackground); setAttribute(Qt::WA_OpaquePaintEvent); - windowHandle = (HWND)winId(); + windowHandle = (HWND) winId(); surfaceInUse = true; RendererCommon::parentWidget = parent; @@ -36,24 +36,36 @@ D3D9Renderer::~D3D9Renderer() finalize(); } -void D3D9Renderer::finalize() +void +D3D9Renderer::finalize() { if (!finalized) { - while (surfaceInUse) {} + while (surfaceInUse) { } finalized = true; } surfaceInUse = true; - if (d3d9surface) { d3d9surface->Release(); d3d9surface = nullptr;} - if (d3d9dev) { d3d9dev->Release(); d3d9dev = nullptr; } - if (d3d9) { d3d9->Release(); d3d9 = nullptr; }; + if (d3d9surface) { + d3d9surface->Release(); + d3d9surface = nullptr; + } + if (d3d9dev) { + d3d9dev->Release(); + d3d9dev = nullptr; + } + if (d3d9) { + d3d9->Release(); + d3d9 = nullptr; + }; } -void D3D9Renderer::hideEvent(QHideEvent *event) +void +D3D9Renderer::hideEvent(QHideEvent *event) { finalize(); } -void D3D9Renderer::showEvent(QShowEvent *event) +void +D3D9Renderer::showEvent(QShowEvent *event) { params = {}; @@ -71,13 +83,15 @@ void D3D9Renderer::showEvent(QShowEvent *event) params.hDeviceWindow = windowHandle; HRESULT result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); - if (FAILED(result)) result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); + if (FAILED(result)) + result = d3d9->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, windowHandle, D3DCREATE_MULTITHREADED | D3DCREATE_SOFTWARE_VERTEXPROCESSING, ¶ms, nullptr, &d3d9dev); if (FAILED(result)) { return error("Failed to create Direct3D 9 device"); } result = d3d9dev->CreateOffscreenPlainSurface(2048, 2048, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); - if (FAILED(result)) result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); + if (FAILED(result)) + result = d3d9dev->CreateOffscreenPlainSurface(1024, 1024, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d9surface, nullptr); if (FAILED(result)) { return error("Failed to create Direct3D 9 surface"); } @@ -86,33 +100,34 @@ void D3D9Renderer::showEvent(QShowEvent *event) alreadyInitialized = true; } surfaceInUse = false; - finalized = false; + finalized = false; } -void D3D9Renderer::paintEvent(QPaintEvent *event) +void +D3D9Renderer::paintEvent(QPaintEvent *event) { - IDirect3DSurface9* backbuffer = nullptr; - RECT srcRect, dstRect; - HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + IDirect3DSurface9 *backbuffer = nullptr; + RECT srcRect, dstRect; + HRESULT result = d3d9dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); if (FAILED(result)) { return; } - srcRect.top = source.top(); + srcRect.top = source.top(); srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); - dstRect.top = destination.top(); + srcRect.left = source.left(); + srcRect.right = source.right(); + dstRect.top = destination.top(); dstRect.bottom = destination.bottom(); - dstRect.left = destination.left(); - dstRect.right = destination.right(); + dstRect.left = destination.left(); + dstRect.right = destination.right(); d3d9dev->BeginScene(); d3d9dev->Clear(0, nullptr, D3DCLEAR_TARGET, 0xFF000000, 0, 0); - while (surfaceInUse) {} + while (surfaceInUse) { } surfaceInUse = true; d3d9dev->StretchRect(d3d9surface, &srcRect, backbuffer, &dstRect, video_filter_method == 0 ? D3DTEXF_POINT : D3DTEXF_LINEAR); - result = d3d9dev->EndScene(); + result = d3d9dev->EndScene(); surfaceInUse = false; if (SUCCEEDED(result)) { if (FAILED(d3d9dev->PresentEx(nullptr, nullptr, 0, nullptr, 0))) { @@ -122,51 +137,57 @@ void D3D9Renderer::paintEvent(QPaintEvent *event) } } -bool D3D9Renderer::event(QEvent *event) +bool +D3D9Renderer::event(QEvent *event) { bool res = false; - if (!eventDelegate(event, res)) return QWidget::event(event); + if (!eventDelegate(event, res)) + return QWidget::event(event); return res; } -void D3D9Renderer::resizeEvent(QResizeEvent *event) +void +D3D9Renderer::resizeEvent(QResizeEvent *event) { onResize(event->size().width() * devicePixelRatioF(), event->size().height() * devicePixelRatioF()); - params.BackBufferWidth = event->size().width() * devicePixelRatioF(); + params.BackBufferWidth = event->size().width() * devicePixelRatioF(); params.BackBufferHeight = event->size().height() * devicePixelRatioF(); - if (d3d9dev) d3d9dev->Reset(¶ms); + if (d3d9dev) + d3d9dev->Reset(¶ms); QWidget::resizeEvent(event); } -void D3D9Renderer::blit(int x, int y, int w, int h) +void +D3D9Renderer::blit(int x, int y, int w, int h) { if (blitDummied || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (monitors[m_monitor_index].target_buffer == NULL) || surfaceInUse) { video_blit_complete_monitor(m_monitor_index); return; } - surfaceInUse = true; + surfaceInUse = true; auto origSource = source; source.setRect(x, y, w, h); - RECT srcRect; + RECT srcRect; D3DLOCKED_RECT lockRect; - srcRect.top = source.top(); + srcRect.top = source.top(); srcRect.bottom = source.bottom(); - srcRect.left = source.left(); - srcRect.right = source.right(); + srcRect.left = source.left(); + srcRect.right = source.right(); if (monitors[m_monitor_index].mon_screenshots) { video_screenshot_monitor((uint32_t *) &(monitors[m_monitor_index].target_buffer->line[y][x]), 0, 0, 2048, m_monitor_index); } if (SUCCEEDED(d3d9surface->LockRect(&lockRect, &srcRect, 0))) { for (int y1 = 0; y1 < h; y1++) { - video_copy(((uint8_t*)lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); + video_copy(((uint8_t *) lockRect.pBits) + (y1 * lockRect.Pitch), &(monitors[m_monitor_index].target_buffer->line[y + y1][x]), w * 4); } video_blit_complete_monitor(m_monitor_index); d3d9surface->UnlockRect(); - } - else video_blit_complete_monitor(m_monitor_index); - if (origSource != source) onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); + } else + video_blit_complete_monitor(m_monitor_index); + if (origSource != source) + onResize(this->width() * devicePixelRatioF(), this->height() * devicePixelRatioF()); surfaceInUse = false; QTimer::singleShot(0, this, [this] { this->update(); }); } diff --git a/src/qt/qt_d3d9renderer.hpp b/src/qt/qt_d3d9renderer.hpp index d93781236..2ec7b0327 100644 --- a/src/qt/qt_d3d9renderer.hpp +++ b/src/qt/qt_d3d9renderer.hpp @@ -8,8 +8,7 @@ #include #include -class D3D9Renderer : public QWidget, public RendererCommon -{ +class D3D9Renderer : public QWidget, public RendererCommon { Q_OBJECT public: explicit D3D9Renderer(QWidget *parent = nullptr, int monitor_index = 0); @@ -19,27 +18,27 @@ public: void finalize() override; protected: - void showEvent(QShowEvent* event) override; - void hideEvent(QHideEvent *event) override; - void resizeEvent(QResizeEvent *event) override; - void paintEvent(QPaintEvent *event) override; - bool event(QEvent* event) override; - QPaintEngine* paintEngine() const override { return nullptr; } + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void paintEvent(QPaintEvent *event) override; + bool event(QEvent *event) override; + QPaintEngine *paintEngine() const override { return nullptr; } signals: void initialized(); void error(QString); private: - HWND windowHandle = 0; - D3DPRESENT_PARAMETERS params{}; - IDirect3D9Ex* d3d9 = nullptr; - IDirect3DDevice9Ex* d3d9dev = nullptr; - IDirect3DSurface9* d3d9surface = nullptr; + HWND windowHandle = 0; + D3DPRESENT_PARAMETERS params {}; + IDirect3D9Ex *d3d9 = nullptr; + IDirect3DDevice9Ex *d3d9dev = nullptr; + IDirect3DSurface9 *d3d9surface = nullptr; - std::atomic surfaceInUse{false}, finalized{false}; - bool alreadyInitialized = false; - int m_monitor_index = 0; + std::atomic surfaceInUse { false }, finalized { false }; + bool alreadyInitialized = false; + int m_monitor_index = 0; }; #endif // D3D9RENDERER_HPP diff --git a/src/qt/qt_deviceconfig.cpp b/src/qt/qt_deviceconfig.cpp index 390a5ab10..81f8b8493 100644 --- a/src/qt/qt_deviceconfig.cpp +++ b/src/qt/qt_deviceconfig.cpp @@ -39,9 +39,9 @@ extern "C" { #include "qt_filefield.hpp" #include "qt_models_common.hpp" -DeviceConfig::DeviceConfig(QWidget *parent) : - QDialog(parent), - ui(new Ui::DeviceConfig) +DeviceConfig::DeviceConfig(QWidget *parent) + : QDialog(parent) + , ui(new Ui::DeviceConfig) { ui->setupUi(this); } @@ -51,7 +51,9 @@ DeviceConfig::~DeviceConfig() delete ui; } -void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Settings* settings) { +void +DeviceConfig::ConfigureDevice(const _device_ *device, int instance, Settings *settings) +{ DeviceConfig dc(settings); dc.setWindowTitle(QString("%1 Device Configuration").arg(device->name)); int c, d, p, q; @@ -59,142 +61,142 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting device_context_t device_context; device_set_context(&device_context, device, instance); - const auto* config = device->config; + const auto *config = device->config; while (config->type != -1) { switch (config->type) { - case CONFIG_BINARY: - { - auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto* cbox = new QCheckBox(); - cbox->setObjectName(config->name); - cbox->setChecked(value > 0); - dc.ui->formLayout->addRow(config->description, cbox); - break; - } + case CONFIG_BINARY: + { + auto value = config_get_int(device_context.name, const_cast(config->name), config->default_int); + auto *cbox = new QCheckBox(); + cbox->setObjectName(config->name); + cbox->setChecked(value > 0); + dc.ui->formLayout->addRow(config->description, cbox); + break; + } #ifdef USE_RTMIDI - case CONFIG_MIDI_OUT: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_out_get_dev_name(i, midiName); + case CONFIG_MIDI_OUT: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + for (int i = 0; i < rtmidi_out_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_out_get_dev_name(i, midiName); - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_MIDI_IN: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { - char midiName[512] = { 0 }; - rtmidi_in_get_dev_name(i, midiName); - - Models::AddEntry(model, midiName, i); - if (selected == i) { - currentIndex = i; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } -#endif - case CONFIG_SELECTION: - case CONFIG_HEX16: - case CONFIG_HEX20: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - int selected = 0; - switch (config->type) { - case CONFIG_SELECTION: - selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX16: - selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); - break; - case CONFIG_HEX20: - selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); - break; - } - - for (auto* sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { - int row = Models::AddEntry(model, sel->description, sel->value); - if (selected == sel->value) { - currentIndex = row; - } - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_BIOS: - { - auto* cbox = new QComboBox(); - cbox->setObjectName(config->name); - auto* model = cbox->model(); - int currentIndex = -1; - char *selected; - selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - - c = q = 0; - for (auto* bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { - p = 0; - for (d = 0; d < bios->files_no; d++) - p += !!rom_present(const_cast(bios->files[d])); - if (p == bios->files_no) { - int row = Models::AddEntry(model, bios->name, q); - if (!strcmp(selected, bios->internal_name)) { - currentIndex = row; + Models::AddEntry(model, midiName, i); + if (selected == i) { + currentIndex = i; + } } - c++; - } - q++; - } - dc.ui->formLayout->addRow(config->description, cbox); - cbox->setCurrentIndex(currentIndex); - break; - } - case CONFIG_SPINNER: - { - int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); - auto* spinBox = new QSpinBox(); - spinBox->setObjectName(config->name); - spinBox->setMaximum(config->spinner.max); - spinBox->setMinimum(config->spinner.min); - if (config->spinner.step > 0) { - spinBox->setSingleStep(config->spinner.step); - } - spinBox->setValue(value); - dc.ui->formLayout->addRow(config->description, spinBox); - break; - } - case CONFIG_FNAME: - { - auto* fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); - auto* fileField = new FileField(); - fileField->setObjectName(config->name); - fileField->setFileName(fileName); - fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); - dc.ui->formLayout->addRow(config->description, fileField); - break; - } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_MIDI_IN: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + int selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + for (int i = 0; i < rtmidi_in_get_num_devs(); i++) { + char midiName[512] = { 0 }; + rtmidi_in_get_dev_name(i, midiName); + + Models::AddEntry(model, midiName, i); + if (selected == i) { + currentIndex = i; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } +#endif + case CONFIG_SELECTION: + case CONFIG_HEX16: + case CONFIG_HEX20: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + int selected = 0; + switch (config->type) { + case CONFIG_SELECTION: + selected = config_get_int(device_context.name, const_cast(config->name), config->default_int); + break; + case CONFIG_HEX16: + selected = config_get_hex16(device_context.name, const_cast(config->name), config->default_int); + break; + case CONFIG_HEX20: + selected = config_get_hex20(device_context.name, const_cast(config->name), config->default_int); + break; + } + + for (auto *sel = config->selection; (sel != nullptr) && (sel->description != nullptr) && (strlen(sel->description) > 0); ++sel) { + int row = Models::AddEntry(model, sel->description, sel->value); + if (selected == sel->value) { + currentIndex = row; + } + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_BIOS: + { + auto *cbox = new QComboBox(); + cbox->setObjectName(config->name); + auto *model = cbox->model(); + int currentIndex = -1; + char *selected; + selected = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + + c = q = 0; + for (auto *bios = config->bios; (bios != nullptr) && (bios->name != nullptr) && (strlen(bios->name) > 0); ++bios) { + p = 0; + for (d = 0; d < bios->files_no; d++) + p += !!rom_present(const_cast(bios->files[d])); + if (p == bios->files_no) { + int row = Models::AddEntry(model, bios->name, q); + if (!strcmp(selected, bios->internal_name)) { + currentIndex = row; + } + c++; + } + q++; + } + dc.ui->formLayout->addRow(config->description, cbox); + cbox->setCurrentIndex(currentIndex); + break; + } + case CONFIG_SPINNER: + { + int value = config_get_int(device_context.name, const_cast(config->name), config->default_int); + auto *spinBox = new QSpinBox(); + spinBox->setObjectName(config->name); + spinBox->setMaximum(config->spinner.max); + spinBox->setMinimum(config->spinner.min); + if (config->spinner.step > 0) { + spinBox->setSingleStep(config->spinner.step); + } + spinBox->setValue(value); + dc.ui->formLayout->addRow(config->description, spinBox); + break; + } + case CONFIG_FNAME: + { + auto *fileName = config_get_string(device_context.name, const_cast(config->name), const_cast(config->default_string)); + auto *fileField = new FileField(); + fileField->setObjectName(config->name); + fileField->setFileName(fileName); + fileField->setFilter(QString(config->file_filter).left(strcspn(config->file_filter, "|"))); + dc.ui->formLayout->addRow(config->description, fileField); + break; + } } ++config; } @@ -205,59 +207,61 @@ void DeviceConfig::ConfigureDevice(const _device_* device, int instance, Setting config = device->config; while (config->type != -1) { switch (config->type) { - case CONFIG_BINARY: - { - auto* cbox = dc.findChild(config->name); - config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); - break; - } - case CONFIG_MIDI_OUT: - case CONFIG_MIDI_IN: - case CONFIG_SELECTION: - { - auto* cbox = dc.findChild(config->name); - config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); - break; - } - case CONFIG_BIOS: - { - auto* cbox = dc.findChild(config->name); - int idx = cbox->currentData().toInt(); - config_set_string(device_context.name, const_cast(config->name), const_cast(config->bios[idx].internal_name)); - break; - } - case CONFIG_HEX16: - { - auto* cbox = dc.findChild(config->name); - config_set_hex16(device_context.name, const_cast(config->name), cbox->currentData().toInt()); - break; - } - case CONFIG_HEX20: - { - auto* cbox = dc.findChild(config->name); - config_set_hex20(device_context.name, const_cast(config->name), cbox->currentData().toInt()); - break; - } - case CONFIG_FNAME: - { - auto* fbox = dc.findChild(config->name); - auto fileName = fbox->fileName().toUtf8(); - config_set_string(device_context.name, const_cast(config->name), fileName.data()); - break; - } - case CONFIG_SPINNER: - { - auto* spinBox = dc.findChild(config->name); - config_set_int(device_context.name, const_cast(config->name), spinBox->value()); - break; - } + case CONFIG_BINARY: + { + auto *cbox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), cbox->isChecked() ? 1 : 0); + break; + } + case CONFIG_MIDI_OUT: + case CONFIG_MIDI_IN: + case CONFIG_SELECTION: + { + auto *cbox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_BIOS: + { + auto *cbox = dc.findChild(config->name); + int idx = cbox->currentData().toInt(); + config_set_string(device_context.name, const_cast(config->name), const_cast(config->bios[idx].internal_name)); + break; + } + case CONFIG_HEX16: + { + auto *cbox = dc.findChild(config->name); + config_set_hex16(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_HEX20: + { + auto *cbox = dc.findChild(config->name); + config_set_hex20(device_context.name, const_cast(config->name), cbox->currentData().toInt()); + break; + } + case CONFIG_FNAME: + { + auto *fbox = dc.findChild(config->name); + auto fileName = fbox->fileName().toUtf8(); + config_set_string(device_context.name, const_cast(config->name), fileName.data()); + break; + } + case CONFIG_SPINNER: + { + auto *spinBox = dc.findChild(config->name); + config_set_int(device_context.name, const_cast(config->name), spinBox->value()); + break; + } } config++; } } } -QString DeviceConfig::DeviceName(const _device_* device, const char *internalName, int bus) { +QString +DeviceConfig::DeviceName(const _device_ *device, const char *internalName, int bus) +{ if (QStringLiteral("none") == internalName) { return tr("None"); } else if (QStringLiteral("internal") == internalName) { diff --git a/src/qt/qt_deviceconfig.hpp b/src/qt/qt_deviceconfig.hpp index 2662df11c..1ed24d618 100644 --- a/src/qt/qt_deviceconfig.hpp +++ b/src/qt/qt_deviceconfig.hpp @@ -15,16 +15,16 @@ class DeviceConfig; class Settings; -class DeviceConfig : public QDialog -{ +class DeviceConfig : public QDialog { Q_OBJECT public: explicit DeviceConfig(QWidget *parent = nullptr); ~DeviceConfig(); - static void ConfigureDevice(const _device_* device, int instance = 0, Settings* settings = nullptr); - static QString DeviceName(const _device_* device, const char* internalName, int bus); + static void ConfigureDevice(const _device_ *device, int instance = 0, Settings *settings = nullptr); + static QString DeviceName(const _device_ *device, const char *internalName, int bus); + private: Ui::DeviceConfig *ui; }; diff --git a/src/qt/qt_filefield.cpp b/src/qt/qt_filefield.cpp index 0639ad0fc..969d5ff29 100644 --- a/src/qt/qt_filefield.cpp +++ b/src/qt/qt_filefield.cpp @@ -21,13 +21,13 @@ #include -FileField::FileField(QWidget *parent) : - QWidget(parent), - ui(new Ui::FileField) +FileField::FileField(QWidget *parent) + : QWidget(parent) + , ui(new Ui::FileField) { ui->setupUi(this); - connect(ui->label, &QLineEdit::editingFinished, this, [this] () { + connect(ui->label, &QLineEdit::editingFinished, this, [this]() { fileName_ = ui->label->text(); emit fileSelected(ui->label->text()); }); @@ -39,12 +39,16 @@ FileField::~FileField() delete ui; } -void FileField::setFileName(const QString &fileName) { +void +FileField::setFileName(const QString &fileName) +{ fileName_ = fileName; ui->label->setText(fileName); } -void FileField::on_pushButton_clicked() { +void +FileField::on_pushButton_clicked() +{ QString fileName; if (createFile_) { fileName = QFileDialog::getSaveFileName(this, QString(), QString(), filter_, &selectedFilter_); diff --git a/src/qt/qt_filefield.hpp b/src/qt/qt_filefield.hpp index 00c4a5e12..8520e3e57 100644 --- a/src/qt/qt_filefield.hpp +++ b/src/qt/qt_filefield.hpp @@ -7,8 +7,7 @@ namespace Ui { class FileField; } -class FileField : public QWidget -{ +class FileField : public QWidget { Q_OBJECT public: @@ -16,26 +15,26 @@ public: ~FileField(); QString fileName() const { return fileName_; } - void setFileName(const QString& fileName); + void setFileName(const QString &fileName); - void setFilter(const QString& filter) { filter_ = filter; } + void setFilter(const QString &filter) { filter_ = filter; } QString selectedFilter() const { return selectedFilter_; } void setCreateFile(bool createFile) { createFile_ = createFile; } bool createFile() { return createFile_; } signals: - void fileSelected(const QString& fileName); + void fileSelected(const QString &fileName); private slots: void on_pushButton_clicked(); private: Ui::FileField *ui; - QString fileName_; - QString selectedFilter_; - QString filter_; - bool createFile_ = false; + QString fileName_; + QString selectedFilter_; + QString filter_; + bool createFile_ = false; }; #endif // QT_FILEFIELD_HPP diff --git a/src/qt/qt_harddiskdialog.cpp b/src/qt/qt_harddiskdialog.cpp index c514b9c48..89de664d8 100644 --- a/src/qt/qt_harddiskdialog.cpp +++ b/src/qt/qt_harddiskdialog.cpp @@ -45,9 +45,9 @@ extern "C" { #include "qt_models_common.hpp" #include "qt_util.hpp" -HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : - QDialog(parent), - ui(new Ui::HarddiskDialog) +HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) + : QDialog(parent) + , ui(new Ui::HarddiskDialog) { ui->setupUi(this); @@ -86,7 +86,7 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : }); } - auto* model = ui->comboBoxFormat->model(); + auto *model = ui->comboBoxFormat->model(); model->insertRows(0, 6); model->setData(model->index(0, 0), tr("Raw image (.img)")); model->setData(model->index(1, 0), tr("HDI image (.hdi)")); @@ -108,9 +108,9 @@ HarddiskDialog::HarddiskDialog(bool existing, QWidget *parent) : model = ui->comboBoxType->model(); for (int i = 0; i < 127; i++) { - uint64_t size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; + uint64_t size = ((uint64_t) hdd_table[i][0]) * hdd_table[i][1] * hdd_table[i][2]; uint32_t size_mb = size >> 11LL; - //QString text = QString("%1 MiB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); + // QString text = QString("%1 MiB (CHS: %2, %3, %4)").arg(size_mb).arg(hdd_table[i][0]).arg(hdd_table[i][1]).arg(hdd_table[i][2]); QString text = QString::asprintf(tr("%u MB (CHS: %i, %i, %i)").toUtf8().constData(), (size_mb), (hdd_table[i][0]), (hdd_table[i][1]), (hdd_table[i][2])); Models::AddEntry(model, text, i); } @@ -126,23 +126,33 @@ HarddiskDialog::~HarddiskDialog() delete ui; } -uint8_t HarddiskDialog::bus() const { +uint8_t +HarddiskDialog::bus() const +{ return static_cast(ui->comboBoxBus->currentData().toUInt()); } -uint8_t HarddiskDialog::channel() const { +uint8_t +HarddiskDialog::channel() const +{ return static_cast(ui->comboBoxChannel->currentData().toUInt()); } -QString HarddiskDialog::fileName() const { +QString +HarddiskDialog::fileName() const +{ return ui->fileField->fileName(); } -uint32_t HarddiskDialog::speed() const { +uint32_t +HarddiskDialog::speed() const +{ return static_cast(ui->comboBoxSpeed->currentData().toUInt()); } -void HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) { +void +HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) +{ bool enabled; if (index == 5) { /* They switched to a diff VHD; disable the geometry fields. */ enabled = false; @@ -177,12 +187,13 @@ void HarddiskDialog::on_comboBoxFormat_currentIndexChanged(int index) { * of about 21 MB, and should only be necessary for VHDs larger than 31.5 GB, so should never be more * than a tenth of a percent change in size. */ -static void adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) +static void +adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *vhd_geometry) { if (_86box_geometry->cyl <= 65535) { - vhd_geometry->cyl = _86box_geometry->cyl; + vhd_geometry->cyl = _86box_geometry->cyl; vhd_geometry->heads = _86box_geometry->heads; - vhd_geometry->spt = _86box_geometry->spt; + vhd_geometry->spt = _86box_geometry->spt; return; } @@ -194,33 +205,35 @@ static void adjust_86box_geometry_for_vhd(MVHDGeom *_86box_geometry, MVHDGeom *v if (remainder > 0) desired_sectors += (85680 - remainder); - _86box_geometry->cyl = desired_sectors / (16 * 63); + _86box_geometry->cyl = desired_sectors / (16 * 63); _86box_geometry->heads = 16; - _86box_geometry->spt = 63; + _86box_geometry->spt = 63; - vhd_geometry->cyl = desired_sectors / (16 * 255); + vhd_geometry->cyl = desired_sectors / (16 * 255); vhd_geometry->heads = 16; - vhd_geometry->spt = 255; + vhd_geometry->spt = 255; } -static HarddiskDialog* callbackPtr = nullptr; -static MVHDGeom create_drive_vhd_fixed(const QString& fileName, HarddiskDialog* p, uint16_t cyl, uint8_t heads, uint8_t spt) { +static HarddiskDialog *callbackPtr = nullptr; +static MVHDGeom +create_drive_vhd_fixed(const QString &fileName, HarddiskDialog *p, uint16_t cyl, uint8_t heads, uint8_t spt) +{ MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; MVHDGeom vhd_geometry; adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - int vhd_error = 0; + int vhd_error = 0; QByteArray filenameBytes = fileName.toUtf8(); - callbackPtr = p; - MVHDMeta *vhd = mvhd_create_fixed(filenameBytes.data(), vhd_geometry, &vhd_error, [](uint32_t current_sector, uint32_t total_sectors) { + callbackPtr = p; + MVHDMeta *vhd = mvhd_create_fixed(filenameBytes.data(), vhd_geometry, &vhd_error, [](uint32_t current_sector, uint32_t total_sectors) { callbackPtr->fileProgress((current_sector * 100) / total_sectors); }); - callbackPtr = nullptr; + callbackPtr = nullptr; if (vhd == NULL) { - _86box_geometry.cyl = 0; + _86box_geometry.cyl = 0; _86box_geometry.heads = 0; - _86box_geometry.spt = 0; + _86box_geometry.spt = 0; } else { mvhd_close(vhd); } @@ -228,24 +241,26 @@ static MVHDGeom create_drive_vhd_fixed(const QString& fileName, HarddiskDialog* return _86box_geometry; } -static MVHDGeom create_drive_vhd_dynamic(const QString& fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) { +static MVHDGeom +create_drive_vhd_dynamic(const QString &fileName, uint16_t cyl, uint8_t heads, uint8_t spt, int blocksize) +{ MVHDGeom _86box_geometry = { .cyl = cyl, .heads = heads, .spt = spt }; MVHDGeom vhd_geometry; adjust_86box_geometry_for_vhd(&_86box_geometry, &vhd_geometry); - int vhd_error = 0; - QByteArray filenameBytes = fileName.toUtf8(); + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); MVHDCreationOptions options; options.block_size_in_sectors = blocksize; - options.path = filenameBytes.data(); - options.size_in_bytes = 0; - options.geometry = vhd_geometry; - options.type = MVHD_TYPE_DYNAMIC; + options.path = filenameBytes.data(); + options.size_in_bytes = 0; + options.geometry = vhd_geometry; + options.type = MVHD_TYPE_DYNAMIC; MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); if (vhd == NULL) { - _86box_geometry.cyl = 0; + _86box_geometry.cyl = 0; _86box_geometry.heads = 0; - _86box_geometry.spt = 0; + _86box_geometry.spt = 0; } else { mvhd_close(vhd); } @@ -253,29 +268,31 @@ static MVHDGeom create_drive_vhd_dynamic(const QString& fileName, uint16_t cyl, return _86box_geometry; } -static MVHDGeom create_drive_vhd_diff(const QString& fileName, const QString& parentFileName, int blocksize) { - int vhd_error = 0; - QByteArray filenameBytes = fileName.toUtf8(); - QByteArray parentFilenameBytes = parentFileName.toUtf8(); +static MVHDGeom +create_drive_vhd_diff(const QString &fileName, const QString &parentFileName, int blocksize) +{ + int vhd_error = 0; + QByteArray filenameBytes = fileName.toUtf8(); + QByteArray parentFilenameBytes = parentFileName.toUtf8(); MVHDCreationOptions options; options.block_size_in_sectors = blocksize; - options.path = filenameBytes.data(); - options.parent_path = parentFilenameBytes.data(); - options.type = MVHD_TYPE_DIFF; + options.path = filenameBytes.data(); + options.parent_path = parentFilenameBytes.data(); + options.type = MVHD_TYPE_DIFF; MVHDMeta *vhd = mvhd_create_ex(options, &vhd_error); - MVHDGeom vhd_geometry; + MVHDGeom vhd_geometry; if (vhd == NULL) { - vhd_geometry.cyl = 0; + vhd_geometry.cyl = 0; vhd_geometry.heads = 0; - vhd_geometry.spt = 0; + vhd_geometry.spt = 0; } else { vhd_geometry = mvhd_get_geometry(vhd); if (vhd_geometry.spt > 63) { - vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); + vhd_geometry.cyl = mvhd_calc_size_sectors(&vhd_geometry) / (16 * 63); vhd_geometry.heads = 16; - vhd_geometry.spt = 63; + vhd_geometry.spt = 63; } mvhd_close(vhd); @@ -284,11 +301,13 @@ static MVHDGeom create_drive_vhd_diff(const QString& fileName, const QString& pa return vhd_geometry; } -void HarddiskDialog::onCreateNewFile() { +void +HarddiskDialog::onCreateNewFile() +{ - for (auto& curObject : children()) - { - if (qobject_cast(curObject)) qobject_cast(curObject)->setDisabled(true); + for (auto &curObject : children()) { + if (qobject_cast(curObject)) + qobject_cast(curObject)->setDisabled(true); } ui->progressBar->setEnabled(true); @@ -299,27 +318,27 @@ void HarddiskDialog::onCreateNewFile() { return; } - int img_format = ui->comboBoxFormat->currentIndex(); - uint32_t zero = 0; - uint32_t base = 0x1000; + int img_format = ui->comboBoxFormat->currentIndex(); + uint32_t zero = 0; + uint32_t base = 0x1000; uint32_t sector_size = 512; - auto fileName = ui->fileField->fileName(); + auto fileName = ui->fileField->fileName(); QString expectedSuffix; switch (img_format) { - case IMG_FMT_HDI: - expectedSuffix = "hdi"; - break; - case IMG_FMT_HDX: - expectedSuffix = "hdx"; - break; - case IMG_FMT_VHD_FIXED: - case IMG_FMT_VHD_DYNAMIC: - case IMG_FMT_VHD_DIFF: - expectedSuffix = "vhd"; - break; + case IMG_FMT_HDI: + expectedSuffix = "hdi"; + break; + case IMG_FMT_HDX: + expectedSuffix = "hdx"; + break; + case IMG_FMT_VHD_FIXED: + case IMG_FMT_VHD_DYNAMIC: + case IMG_FMT_VHD_DIFF: + expectedSuffix = "vhd"; + break; } - if (! expectedSuffix.isEmpty()) { + if (!expectedSuffix.isEmpty()) { QFileInfo fileInfo(fileName); if (fileInfo.suffix().compare(expectedSuffix, Qt::CaseInsensitive) != 0) { fileName = QString("%1.%2").arg(fileName, expectedSuffix); @@ -331,7 +350,7 @@ void HarddiskDialog::onCreateNewFile() { ui->fileField->setFileName(fileName); QFile file(fileName); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); return; } @@ -344,14 +363,14 @@ void HarddiskDialog::onCreateNewFile() { return; } uint32_t s = static_cast(size); - stream << zero; /* 00000000: Zero/unknown */ - stream << zero; /* 00000004: Zero/unknown */ - stream << base; /* 00000008: Offset at which data starts */ - stream << s; /* 0000000C: Full size of the data (32-bit) */ - stream << sector_size; /* 00000010: Sector size in bytes */ - stream << sectors_; /* 00000014: Sectors per cylinder */ - stream << heads_; /* 00000018: Heads per cylinder */ - stream << cylinders_; /* 0000001C: Cylinders */ + stream << zero; /* 00000000: Zero/unknown */ + stream << zero; /* 00000004: Zero/unknown */ + stream << base; /* 00000008: Offset at which data starts */ + stream << s; /* 0000000C: Full size of the data (32-bit) */ + stream << sector_size; /* 00000010: Sector size in bytes */ + stream << sectors_; /* 00000014: Sectors per cylinder */ + stream << heads_; /* 00000018: Heads per cylinder */ + stream << cylinders_; /* 0000001C: Cylinders */ for (int i = 0; i < 0x3f8; i++) { stream << zero; @@ -360,57 +379,50 @@ void HarddiskDialog::onCreateNewFile() { QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); quint64 signature = 0xD778A82044445459; - stream << signature; /* 00000000: Signature */ - stream << size; /* 00000008: Full size of the data (64-bit) */ - stream << sector_size; /* 00000010: Sector size in bytes */ - stream << sectors_; /* 00000014: Sectors per cylinder */ - stream << heads_; /* 00000018: Heads per cylinder */ - stream << cylinders_; /* 0000001C: Cylinders */ - stream << zero; /* 00000020: [Translation] Sectors per cylinder */ - stream << zero; /* 00000004: [Translation] Heads per cylinder */ + stream << signature; /* 00000000: Signature */ + stream << size; /* 00000008: Full size of the data (64-bit) */ + stream << sector_size; /* 00000010: Sector size in bytes */ + stream << sectors_; /* 00000014: Sectors per cylinder */ + stream << heads_; /* 00000018: Heads per cylinder */ + stream << cylinders_; /* 0000001C: Cylinders */ + stream << zero; /* 00000020: [Translation] Sectors per cylinder */ + stream << zero; /* 00000004: [Translation] Heads per cylinder */ } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ file.close(); - MVHDGeom _86box_geometry{}; - int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; + MVHDGeom _86box_geometry {}; + int block_size = ui->comboBoxBlockSize->currentIndex() == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { - case IMG_FMT_VHD_FIXED: - { - connect(this, &HarddiskDialog::fileProgress, this, [this] (int value) { ui->progressBar->setValue(value); QApplication::processEvents(); } ); - ui->progressBar->setVisible(true); - [&_86box_geometry, fileName, this] { - _86box_geometry = create_drive_vhd_fixed(fileName, this, cylinders_, heads_, sectors_); - }(); - } - break; - case IMG_FMT_VHD_DYNAMIC: - _86box_geometry = create_drive_vhd_dynamic(fileName, cylinders_, heads_, sectors_, block_size); - break; - case IMG_FMT_VHD_DIFF: - QString vhdParent = QFileDialog::getOpenFileName( - this, - tr("Select the parent VHD"), - QString(), - tr("VHD files") % - util::DlgFilter({ "vhd" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + case IMG_FMT_VHD_FIXED: + { + connect(this, &HarddiskDialog::fileProgress, this, [this](int value) { ui->progressBar->setValue(value); QApplication::processEvents(); }); + ui->progressBar->setVisible(true); + [&_86box_geometry, fileName, this] { + _86box_geometry = create_drive_vhd_fixed(fileName, this, cylinders_, heads_, sectors_); + }(); + } + break; + case IMG_FMT_VHD_DYNAMIC: + _86box_geometry = create_drive_vhd_dynamic(fileName, cylinders_, heads_, sectors_, block_size); + break; + case IMG_FMT_VHD_DIFF: + QString vhdParent = QFileDialog::getOpenFileName( + this, + tr("Select the parent VHD"), + QString(), + tr("VHD files") % util::DlgFilter({ "vhd" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - if (vhdParent.isEmpty()) { - return; - } - _86box_geometry = create_drive_vhd_diff(fileName, vhdParent, block_size); - break; + if (vhdParent.isEmpty()) { + return; + } + _86box_geometry = create_drive_vhd_diff(fileName, vhdParent, block_size); + break; } - if (_86box_geometry.cyl == 0 && - _86box_geometry.heads == 0 && - _86box_geometry.spt == 0) - { + if (_86box_geometry.cyl == 0 && _86box_geometry.heads == 0 && _86box_geometry.spt == 0) { QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory.")); return; - } - else if (img_format != IMG_FMT_VHD_DIFF) { + } else if (img_format != IMG_FMT_VHD_DIFF) { QMessageBox::information(this, tr("Disk image created"), tr("Remember to partition and format the newly-created drive.")); } @@ -418,23 +430,23 @@ void HarddiskDialog::onCreateNewFile() { ui->lineEditHeads->setText(QString::number(_86box_geometry.heads)); ui->lineEditSectors->setText(QString::number(_86box_geometry.spt)); cylinders_ = _86box_geometry.cyl; - heads_ = _86box_geometry.heads; - sectors_ = _86box_geometry.spt; + heads_ = _86box_geometry.heads; + sectors_ = _86box_geometry.spt; setResult(QDialog::Accepted); return; } // formats 0, 1 and 2 - connect(this, &HarddiskDialog::fileProgress, this, [this] (int value) { ui->progressBar->setValue(value); QApplication::processEvents(); } ); + connect(this, &HarddiskDialog::fileProgress, this, [this](int value) { ui->progressBar->setValue(value); QApplication::processEvents(); }); ui->progressBar->setVisible(true); [size, &file, this] { QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); QByteArray buf(1048576, 0); - uint64_t mibBlocks = size >> 20; - uint64_t restBlock = size & 0xfffff; + uint64_t mibBlocks = size >> 20; + uint64_t restBlock = size & 0xfffff; if (restBlock) { stream.writeRawData(buf.data(), restBlock); @@ -453,7 +465,9 @@ void HarddiskDialog::onCreateNewFile() { setResult(QDialog::Accepted); } -static void adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) { +static void +adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) +{ if (vhd_geometry->spt <= 63) return; @@ -465,17 +479,17 @@ static void adjust_vhd_geometry_for_86box(MVHDGeom *vhd_geometry) { if (remainder > 0) desired_sectors -= remainder; - vhd_geometry->cyl = desired_sectors / (16 * 63); + vhd_geometry->cyl = desired_sectors / (16 * 63); vhd_geometry->heads = 16; - vhd_geometry->spt = 63; + vhd_geometry->spt = 63; } -void HarddiskDialog::recalcSelection() { +void +HarddiskDialog::recalcSelection() +{ int selection = 127; for (int i = 0; i < 127; i++) { - if ((cylinders_ == hdd_table[i][0]) && - (heads_ == hdd_table[i][1]) && - (sectors_ == hdd_table[i][2])) + if ((cylinders_ == hdd_table[i][0]) && (heads_ == hdd_table[i][1]) && (sectors_ == hdd_table[i][2])) selection = i; } if ((selection == 127) && (heads_ == 16) && (sectors_ == 63)) { @@ -484,7 +498,9 @@ void HarddiskDialog::recalcSelection() { ui->comboBoxType->setCurrentIndex(selection); } -void HarddiskDialog::onExistingFileSelected(const QString &fileName) { +void +HarddiskDialog::onExistingFileSelected(const QString &fileName) +{ // TODO : Over to non-existing file selected /* if (!(existing & 1)) { @@ -505,16 +521,16 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { } */ - uint64_t size = 0; + uint64_t size = 0; uint32_t sector_size = 0; - uint32_t sectors = 0; - uint32_t heads = 0; - uint32_t cylinders = 0; - int vhd_error = 0; + uint32_t sectors = 0; + uint32_t heads = 0; + uint32_t cylinders = 0; + int vhd_error = 0; ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); QFile file(fileName); - if (! file.open(QIODevice::ReadOnly)) { + if (!file.open(QIODevice::ReadOnly)) { QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable.")); return; } @@ -536,7 +552,7 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { stream >> heads; stream >> cylinders; } else if (image_is_vhd(fileNameUtf8.data(), 1)) { - MVHDMeta* vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); + MVHDMeta *vhd = mvhd_open(fileNameUtf8.data(), 0, &vhd_error); if (vhd == nullptr) { QMessageBox::critical(this, tr("Unable to read file"), tr("Make sure the file exists and is readable")); return; @@ -558,9 +574,9 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { MVHDGeom vhd_geom = mvhd_get_geometry(vhd); adjust_vhd_geometry_for_86box(&vhd_geom); cylinders = vhd_geom.cyl; - heads = vhd_geom.heads; - sectors = vhd_geom.spt; - size = static_cast(cylinders * heads * sectors * 512); + heads = vhd_geom.heads; + sectors = vhd_geom.spt; + size = static_cast(cylinders * heads * sectors * 512); mvhd_close(vhd); } else { size = file.size(); @@ -582,7 +598,7 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { } } else { sectors = 63; - heads = 16; + heads = 16; } cylinders = ((size >> 9) / heads) / sectors; @@ -593,8 +609,8 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { return; } - heads_ = heads; - sectors_ = sectors; + heads_ = heads; + sectors_ = sectors; cylinders_ = cylinders; ui->lineEditCylinders->setText(QString::number(cylinders)); ui->lineEditHeads->setText(QString::number(heads)); @@ -610,13 +626,18 @@ void HarddiskDialog::onExistingFileSelected(const QString &fileName) { ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true); } -void HarddiskDialog::recalcSize() { - if (disallowSizeModifications) return; +void +HarddiskDialog::recalcSize() +{ + if (disallowSizeModifications) + return; uint64_t size = (static_cast(cylinders_) * static_cast(heads_) * static_cast(sectors_)) << 9; ui->lineEditSize->setText(QString::number(size >> 20)); } -bool HarddiskDialog::checkAndAdjustSectors() { +bool +HarddiskDialog::checkAndAdjustSectors() +{ if (sectors_ > max_sectors) { sectors_ = max_sectors; ui->lineEditSectors->setText(QString::number(max_sectors)); @@ -627,7 +648,9 @@ bool HarddiskDialog::checkAndAdjustSectors() { return true; } -bool HarddiskDialog::checkAndAdjustHeads() { +bool +HarddiskDialog::checkAndAdjustHeads() +{ if (heads_ > max_heads) { heads_ = max_heads; ui->lineEditHeads->setText(QString::number(max_heads)); @@ -638,7 +661,9 @@ bool HarddiskDialog::checkAndAdjustHeads() { return true; } -bool HarddiskDialog::checkAndAdjustCylinders() { +bool +HarddiskDialog::checkAndAdjustCylinders() +{ if (cylinders_ > max_cylinders) { cylinders_ = max_cylinders; ui->lineEditCylinders->setText(QString::number(max_cylinders)); @@ -649,44 +674,45 @@ bool HarddiskDialog::checkAndAdjustCylinders() { return true; } - -void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { +void +HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) +{ int chanIdx = 0; if (index < 0) { return; } switch (ui->comboBoxBus->currentData().toInt()) { - case HDD_BUS_DISABLED: - default: - max_sectors = max_heads = max_cylinders = 0; - break; - case HDD_BUS_MFM: - max_sectors = 26; /* 17 for MFM, 26 for RLL. */ - max_heads = 15; - max_cylinders = 2047; - break; - case HDD_BUS_XTA: - max_sectors = 63; - max_heads = 16; - max_cylinders = 1023; - break; - case HDD_BUS_ESDI: - max_sectors = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ - max_heads = 16; - max_cylinders = 266305; - break; - case HDD_BUS_IDE: - max_sectors = 63; - max_heads = 255; - max_cylinders = 266305; - break; - case HDD_BUS_ATAPI: - case HDD_BUS_SCSI: - max_sectors = 99; - max_heads = 255; - max_cylinders = 266305; - break; + case HDD_BUS_DISABLED: + default: + max_sectors = max_heads = max_cylinders = 0; + break; + case HDD_BUS_MFM: + max_sectors = 26; /* 17 for MFM, 26 for RLL. */ + max_heads = 15; + max_cylinders = 2047; + break; + case HDD_BUS_XTA: + max_sectors = 63; + max_heads = 16; + max_cylinders = 1023; + break; + case HDD_BUS_ESDI: + max_sectors = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ + max_heads = 16; + max_cylinders = 266305; + break; + case HDD_BUS_IDE: + max_sectors = 63; + max_heads = 255; + max_cylinders = 266305; + break; + case HDD_BUS_ATAPI: + case HDD_BUS_SCSI: + max_sectors = 99; + max_heads = 255; + max_cylinders = 266305; + break; } checkAndAdjustCylinders(); @@ -710,8 +736,7 @@ void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { Harddrives::populateBusChannels(ui->comboBoxChannel->model(), ui->comboBoxBus->currentData().toInt()); Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); - switch (ui->comboBoxBus->currentData().toInt()) - { + switch (ui->comboBoxBus->currentData().toInt()) { case HDD_BUS_MFM: chanIdx = (Harddrives::busTrackClass->next_free_mfm_channel()); break; @@ -730,13 +755,16 @@ void HarddiskDialog::on_comboBoxBus_currentIndexChanged(int index) { break; } - if (chanIdx == 0xFF) chanIdx = 0; + if (chanIdx == 0xFF) + chanIdx = 0; ui->comboBoxChannel->setCurrentIndex(chanIdx); } -void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditSize_textEdited(const QString &text) +{ disallowSizeModifications = true; - uint32_t size = text.toUInt(); + uint32_t size = text.toUInt(); /* This is needed to ensure VHD standard compliance. */ hdd_image_calc_chs(&cylinders_, &heads_, §ors_, size); ui->lineEditCylinders->setText(QString::number(cylinders_)); @@ -751,7 +779,9 @@ void HarddiskDialog::on_lineEditSize_textEdited(const QString &text) { disallowSizeModifications = false; } -void HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) +{ cylinders_ = text.toUInt(); if (checkAndAdjustCylinders()) { recalcSize(); @@ -759,7 +789,9 @@ void HarddiskDialog::on_lineEditCylinders_textEdited(const QString &text) { } } -void HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) +{ heads_ = text.toUInt(); if (checkAndAdjustHeads()) { recalcSize(); @@ -767,7 +799,9 @@ void HarddiskDialog::on_lineEditHeads_textEdited(const QString &text) { } } -void HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) { +void +HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) +{ sectors_ = text.toUInt(); if (checkAndAdjustSectors()) { recalcSize(); @@ -775,21 +809,23 @@ void HarddiskDialog::on_lineEditSectors_textEdited(const QString &text) { } } -void HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) { +void +HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) +{ if (index < 0) { return; } if ((index != 127) && (index != 128)) { cylinders_ = hdd_table[index][0]; - heads_ = hdd_table[index][1]; - sectors_ = hdd_table[index][2]; + heads_ = hdd_table[index][1]; + sectors_ = hdd_table[index][2]; ui->lineEditCylinders->setText(QString::number(cylinders_)); ui->lineEditHeads->setText(QString::number(heads_)); ui->lineEditSectors->setText(QString::number(sectors_)); recalcSize(); } else if (index == 128) { - heads_ = 16; + heads_ = 16; sectors_ = 63; ui->lineEditHeads->setText(QString::number(heads_)); ui->lineEditSectors->setText(QString::number(sectors_)); @@ -801,9 +837,12 @@ void HarddiskDialog::on_comboBoxType_currentIndexChanged(int index) { checkAndAdjustSectors(); } -void HarddiskDialog::accept() +void +HarddiskDialog::accept() { - if (ui->fileField->createFile()) onCreateNewFile(); - else setResult(QDialog::Accepted); + if (ui->fileField->createFile()) + onCreateNewFile(); + else + setResult(QDialog::Accepted); QDialog::done(result()); } diff --git a/src/qt/qt_harddiskdialog.hpp b/src/qt/qt_harddiskdialog.hpp index f876d35dd..a630bd8e2 100644 --- a/src/qt/qt_harddiskdialog.hpp +++ b/src/qt/qt_harddiskdialog.hpp @@ -7,17 +7,16 @@ namespace Ui { class HarddiskDialog; } -class HarddiskDialog : public QDialog -{ +class HarddiskDialog : public QDialog { Q_OBJECT public: explicit HarddiskDialog(bool existing, QWidget *parent = nullptr); ~HarddiskDialog(); - uint8_t bus() const; - uint8_t channel() const; - QString fileName() const; + uint8_t bus() const; + uint8_t channel() const; + QString fileName() const; uint32_t cylinders() const { return cylinders_; } uint32_t heads() const { return heads_; } uint32_t sectors() const { return sectors_; } @@ -38,7 +37,8 @@ private slots: void on_comboBoxBus_currentIndexChanged(int index); void on_comboBoxFormat_currentIndexChanged(int index); void onCreateNewFile(); - void onExistingFileSelected(const QString& fileName); + void onExistingFileSelected(const QString &fileName); + private: Ui::HarddiskDialog *ui; @@ -46,10 +46,10 @@ private: uint32_t heads_; uint32_t sectors_; - uint32_t max_sectors = 0; - uint32_t max_heads = 0; + uint32_t max_sectors = 0; + uint32_t max_heads = 0; uint32_t max_cylinders = 0; - + bool disallowSizeModifications = false; bool checkAndAdjustCylinders(); diff --git a/src/qt/qt_harddrive_common.cpp b/src/qt/qt_harddrive_common.cpp index 661e7992c..7d3beaa2b 100644 --- a/src/qt/qt_harddrive_common.cpp +++ b/src/qt/qt_harddrive_common.cpp @@ -24,7 +24,9 @@ extern "C" { #include -void Harddrives::populateBuses(QAbstractItemModel *model) { +void +Harddrives::populateBuses(QAbstractItemModel *model) +{ model->removeRows(0, model->rowCount()); model->insertRows(0, 6); model->setData(model->index(0, 0), "MFM/RLL"); @@ -42,7 +44,9 @@ void Harddrives::populateBuses(QAbstractItemModel *model) { model->setData(model->index(5, 0), HDD_BUS_SCSI, Qt::UserRole); } -void Harddrives::populateRemovableBuses(QAbstractItemModel *model) { +void +Harddrives::populateRemovableBuses(QAbstractItemModel *model) +{ model->removeRows(0, model->rowCount()); model->insertRows(0, 3); model->setData(model->index(0, 0), QObject::tr("Disabled")); @@ -54,7 +58,9 @@ void Harddrives::populateRemovableBuses(QAbstractItemModel *model) { model->setData(model->index(2, 0), HDD_BUS_SCSI, Qt::UserRole); } -void Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) { +void +Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) +{ int num_preset; switch (bus) { @@ -76,29 +82,31 @@ void Harddrives::populateSpeeds(QAbstractItemModel *model, int bus) { } } -void Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) { +void +Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) +{ model->removeRows(0, model->rowCount()); - int busRows = 0; - int shifter = 1; - int orer = 1; + int busRows = 0; + int shifter = 1; + int orer = 1; int subChannelWidth = 1; switch (bus) { - case HDD_BUS_MFM: - case HDD_BUS_XTA: - case HDD_BUS_ESDI: - busRows = 2; - break; - case HDD_BUS_IDE: - case HDD_BUS_ATAPI: - busRows = 8; - break; - case HDD_BUS_SCSI: - shifter = 4; - orer = 15; - busRows = 64; - subChannelWidth = 2; - break; + case HDD_BUS_MFM: + case HDD_BUS_XTA: + case HDD_BUS_ESDI: + busRows = 2; + break; + case HDD_BUS_IDE: + case HDD_BUS_ATAPI: + busRows = 8; + break; + case HDD_BUS_SCSI: + shifter = 4; + orer = 15; + busRows = 64; + subChannelWidth = 2; + break; } model->insertRows(0, busRows); @@ -109,30 +117,32 @@ void Harddrives::populateBusChannels(QAbstractItemModel *model, int bus) { } } -QString Harddrives::BusChannelName(uint8_t bus, uint8_t channel) { +QString +Harddrives::BusChannelName(uint8_t bus, uint8_t channel) +{ QString busName; - switch(bus) { - case HDD_BUS_DISABLED: - busName = QString(QObject::tr("Disabled")); - break; - case HDD_BUS_MFM: - busName = QString("MFM/RLL (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_XTA: - busName = QString("XTA (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_ESDI: - busName = QString("ESDI (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_IDE: - busName = QString("IDE (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_ATAPI: - busName = QString("ATAPI (%1:%2)").arg(channel >> 1).arg(channel & 1); - break; - case HDD_BUS_SCSI: - busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0')); - break; + switch (bus) { + case HDD_BUS_DISABLED: + busName = QString(QObject::tr("Disabled")); + break; + case HDD_BUS_MFM: + busName = QString("MFM/RLL (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_XTA: + busName = QString("XTA (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_ESDI: + busName = QString("ESDI (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_IDE: + busName = QString("IDE (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_ATAPI: + busName = QString("ATAPI (%1:%2)").arg(channel >> 1).arg(channel & 1); + break; + case HDD_BUS_SCSI: + busName = QString("SCSI (%1:%2)").arg(channel >> 4).arg(channel & 15, 2, 10, QChar('0')); + break; } return busName; diff --git a/src/qt/qt_harddrive_common.hpp b/src/qt/qt_harddrive_common.hpp index 6e133506f..2aca184b3 100644 --- a/src/qt/qt_harddrive_common.hpp +++ b/src/qt/qt_harddrive_common.hpp @@ -7,10 +7,10 @@ class QAbstractItemModel; class SettingsBusTracking; namespace Harddrives { - void populateBuses(QAbstractItemModel* model); - void populateRemovableBuses(QAbstractItemModel* model); - void populateBusChannels(QAbstractItemModel* model, int bus); - void populateSpeeds(QAbstractItemModel* model, int bus); - QString BusChannelName(uint8_t bus, uint8_t channel); - inline SettingsBusTracking* busTrackClass = nullptr; +void populateBuses(QAbstractItemModel *model); +void populateRemovableBuses(QAbstractItemModel *model); +void populateBusChannels(QAbstractItemModel *model, int bus); +void populateSpeeds(QAbstractItemModel *model, int bus); +QString BusChannelName(uint8_t bus, uint8_t channel); +inline SettingsBusTracking *busTrackClass = nullptr; }; diff --git a/src/qt/qt_hardwarerenderer.cpp b/src/qt/qt_hardwarerenderer.cpp index dd0eed632..f158e7d62 100644 --- a/src/qt/qt_hardwarerenderer.cpp +++ b/src/qt/qt_hardwarerenderer.cpp @@ -33,85 +33,77 @@ extern "C" { #include <86box/video.h> } -void HardwareRenderer::resizeGL(int w, int h) +void +HardwareRenderer::resizeGL(int w, int h) { m_context->makeCurrent(this); glViewport(0, 0, qRound(w * devicePixelRatio()), qRound(h * devicePixelRatio())); } -#define PROGRAM_VERTEX_ATTRIBUTE 0 +#define PROGRAM_VERTEX_ATTRIBUTE 0 #define PROGRAM_TEXCOORD_ATTRIBUTE 1 -void HardwareRenderer::initializeGL() +void +HardwareRenderer::initializeGL() { m_context->makeCurrent(this); initializeOpenGLFunctions(); auto image = QImage(2048, 2048, QImage::Format_RGB32); image.fill(0xff000000); m_texture = new QOpenGLTexture(image); - m_blt = new QOpenGLTextureBlitter; + m_blt = new QOpenGLTextureBlitter; m_blt->setRedBlueSwizzle(true); m_blt->create(); - QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); - const char *vsrc = - "attribute highp vec4 VertexCoord;\n" - "attribute mediump vec4 TexCoord;\n" - "varying mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - QString vsrccore = - "in highp vec4 VertexCoord;\n" - "in mediump vec4 TexCoord;\n" - "out mediump vec4 texc;\n" - "uniform mediump mat4 MVPMatrix;\n" - "void main(void)\n" - "{\n" - " gl_Position = MVPMatrix * VertexCoord;\n" - " texc = TexCoord;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) - { + QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this); + const char *vsrc = "attribute highp vec4 VertexCoord;\n" + "attribute mediump vec4 TexCoord;\n" + "varying mediump vec4 texc;\n" + "uniform mediump mat4 MVPMatrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = MVPMatrix * VertexCoord;\n" + " texc = TexCoord;\n" + "}\n"; + QString vsrccore = "in highp vec4 VertexCoord;\n" + "in mediump vec4 TexCoord;\n" + "out mediump vec4 texc;\n" + "uniform mediump mat4 MVPMatrix;\n" + "void main(void)\n" + "{\n" + " gl_Position = MVPMatrix * VertexCoord;\n" + " texc = TexCoord;\n" + "}\n"; + if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { vsrccore.prepend("#version 300 es\n"); vshader->compileSourceCode(vsrccore); - } - else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) - { + } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { vsrccore.prepend("#version 130\n"); vshader->compileSourceCode(vsrccore); - } - else vshader->compileSourceCode(vsrc); + } else + vshader->compileSourceCode(vsrc); - QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); - const char *fsrc = - "uniform sampler2D texture;\n" - "varying mediump vec4 texc;\n" - "void main(void)\n" - "{\n" - " gl_FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - QString fsrccore = - "uniform sampler2D texture;\n" - "in mediump vec4 texc;\n" - "out highp vec4 FragColor;\n" - "void main(void)\n" - "{\n" - " FragColor = texture2D(texture, texc.st).bgra;\n" - "}\n"; - if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) - { + QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this); + const char *fsrc = "uniform sampler2D texture;\n" + "varying mediump vec4 texc;\n" + "void main(void)\n" + "{\n" + " gl_FragColor = texture2D(texture, texc.st).bgra;\n" + "}\n"; + QString fsrccore = "uniform sampler2D texture;\n" + "in mediump vec4 texc;\n" + "out highp vec4 FragColor;\n" + "void main(void)\n" + "{\n" + " FragColor = texture2D(texture, texc.st).bgra;\n" + "}\n"; + if (m_context->isOpenGLES() && m_context->format().version() >= qMakePair(3, 0)) { fsrccore.prepend("#version 300 es\n"); fshader->compileSourceCode(fsrccore); - } - else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) - { + } else if (m_context->format().version() >= qMakePair(3, 0) && m_context->format().profile() == QSurfaceFormat::CoreProfile) { fsrccore.prepend("#version 130\n"); fshader->compileSourceCode(fsrccore); - } - else fshader->compileSourceCode(fsrc); + } else + fshader->compileSourceCode(fsrc); m_prog = new QOpenGLShaderProgram; m_prog->addShader(vshader); @@ -144,95 +136,115 @@ void HardwareRenderer::initializeGL() m_context->swapBuffers(this); } -void HardwareRenderer::paintGL() { +void +HardwareRenderer::paintGL() +{ m_context->makeCurrent(this); glClear(GL_COLOR_BUFFER_BIT); QVector verts, texcoords; - QMatrix4x4 mat; + QMatrix4x4 mat; mat.setToIdentity(); - mat.ortho(QRectF(0, 0, (qreal)width(), (qreal)height())); - verts.push_back(QVector2D((float)destination.x(), (float)destination.y())); - verts.push_back(QVector2D((float)destination.x(), (float)destination.y() + (float)destination.height())); - verts.push_back(QVector2D((float)destination.x() + (float)destination.width(), (float)destination.y() + (float)destination.height())); - verts.push_back(QVector2D((float)destination.x() + (float)destination.width(), (float)destination.y())); - texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y()) / 2048.f)); - texcoords.push_back(QVector2D((float)source.x() / 2048.f, (float)(source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y() + source.height()) / 2048.f)); - texcoords.push_back(QVector2D((float)(source.x() + source.width()) / 2048.f, (float)(source.y()) / 2048.f)); + mat.ortho(QRectF(0, 0, (qreal) width(), (qreal) height())); + verts.push_back(QVector2D((float) destination.x(), (float) destination.y())); + verts.push_back(QVector2D((float) destination.x(), (float) destination.y() + (float) destination.height())); + verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y() + (float) destination.height())); + verts.push_back(QVector2D((float) destination.x() + (float) destination.width(), (float) destination.y())); + texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y()) / 2048.f)); + texcoords.push_back(QVector2D((float) source.x() / 2048.f, (float) (source.y() + source.height()) / 2048.f)); + texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y() + source.height()) / 2048.f)); + texcoords.push_back(QVector2D((float) (source.x() + source.width()) / 2048.f, (float) (source.y()) / 2048.f)); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].write(0, verts.data(), sizeof(QVector2D) * 4); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].write(0, texcoords.data(), sizeof(QVector2D) * 4); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); m_prog->setUniformValue("MVPMatrix", mat); m_prog->enableAttributeArray(PROGRAM_VERTEX_ATTRIBUTE); m_prog->enableAttributeArray(PROGRAM_TEXCOORD_ATTRIBUTE); - m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); - m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].bind(); + m_prog->setAttributeBuffer(PROGRAM_VERTEX_ATTRIBUTE, GL_FLOAT, 0, 2, 0); + m_vbo[PROGRAM_VERTEX_ATTRIBUTE].release(); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].bind(); + m_prog->setAttributeBuffer(PROGRAM_TEXCOORD_ATTRIBUTE, GL_FLOAT, 0, 2, 0); + m_vbo[PROGRAM_TEXCOORD_ATTRIBUTE].release(); m_texture->bind(); m_texture->setMinMagFilters(video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest, video_filter_method ? QOpenGLTexture::Linear : QOpenGLTexture::Nearest); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } -void HardwareRenderer::setRenderType(RenderType type) { +void +HardwareRenderer::setRenderType(RenderType type) +{ QSurfaceFormat format; switch (type) { - case RenderType::OpenGL3: - format.setVersion(3, 0); - format.setProfile(QSurfaceFormat::CoreProfile); - case RenderType::OpenGL: - format.setRenderableType(QSurfaceFormat::OpenGL); - break; - case RenderType::OpenGLES: - format.setRenderableType(QSurfaceFormat::OpenGLES); - break; + case RenderType::OpenGL3: + format.setVersion(3, 0); + format.setProfile(QSurfaceFormat::CoreProfile); + case RenderType::OpenGL: + format.setRenderableType(QSurfaceFormat::OpenGL); + break; + case RenderType::OpenGLES: + format.setRenderableType(QSurfaceFormat::OpenGLES); + break; } format.setSwapInterval(0); setFormat(format); } -void HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { - auto tval = this; - void* nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; +void +HardwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +{ + auto tval = this; + void *nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) + return; auto origSource = source; - if (!m_texture || !m_texture->isCreated()) - { + if (!m_texture || !m_texture->isCreated()) { buf_usage[buf_idx].clear(); source.setRect(x, y, w, h); return; } m_context->makeCurrent(this); #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) - m_texture->setData(x, y, 0, w, h, 0, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)((uintptr_t)imagebufs[buf_idx].get() + (uintptr_t)(2048 * 4 * y + x * 4)), &m_transferOptions); + m_texture->setData(x, y, 0, w, h, 0, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4)), &m_transferOptions); #else m_texture->bind(); glPixelStorei(GL_UNPACK_ROW_LENGTH, 2048); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void*)((uintptr_t)imagebufs[buf_idx].get() + (uintptr_t)(2048 * 4 * y + x * 4))); + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, QOpenGLTexture::PixelFormat::RGBA, QOpenGLTexture::PixelType::UInt8, (const void *) ((uintptr_t) imagebufs[buf_idx].get() + (uintptr_t) (2048 * 4 * y + x * 4))); m_texture->release(); #endif buf_usage[buf_idx].clear(); source.setRect(x, y, w, h); - if (origSource != source) onResize(this->width(), this->height()); + if (origSource != source) + onResize(this->width(), this->height()); update(); } -void HardwareRenderer::resizeEvent(QResizeEvent *event) { +void +HardwareRenderer::resizeEvent(QResizeEvent *event) +{ onResize(width(), height()); QOpenGLWindow::resizeEvent(event); } -bool HardwareRenderer::event(QEvent *event) +bool +HardwareRenderer::event(QEvent *event) { bool res = false; - if (!eventDelegate(event, res)) return QOpenGLWindow::event(event); + if (!eventDelegate(event, res)) + return QOpenGLWindow::event(event); return res; } -std::vector> HardwareRenderer::getBuffers() +std::vector> +HardwareRenderer::getBuffers() { - std::vector> buffers; + std::vector> buffers; buffers.push_back(std::make_tuple(imagebufs[0].get(), &buf_usage[0])); buffers.push_back(std::make_tuple(imagebufs[1].get(), &buf_usage[1])); diff --git a/src/qt/qt_hardwarerenderer.hpp b/src/qt/qt_hardwarerenderer.hpp index 30515a2e8..da23c4b05 100644 --- a/src/qt/qt_hardwarerenderer.hpp +++ b/src/qt/qt_hardwarerenderer.hpp @@ -24,21 +24,20 @@ #include "qt_renderercommon.hpp" #ifdef WAYLAND -#include "wl_mouse.hpp" +# include "wl_mouse.hpp" #endif -class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon -{ - Q_OBJECT +class HardwareRenderer : public QOpenGLWindow, protected QOpenGLFunctions, public RendererCommon { + Q_OBJECT private: - bool wayland = false; - QOpenGLContext* m_context; - QOpenGLTexture* m_texture{nullptr}; - QOpenGLShaderProgram* m_prog{nullptr}; - QOpenGLTextureBlitter* m_blt{nullptr}; - QOpenGLBuffer m_vbo[2]; - QOpenGLVertexArrayObject m_vao; + bool wayland = false; + QOpenGLContext *m_context; + QOpenGLTexture *m_texture { nullptr }; + QOpenGLShaderProgram *m_prog { nullptr }; + QOpenGLTextureBlitter *m_blt { nullptr }; + QOpenGLBuffer m_vbo[2]; + QOpenGLVertexArrayObject m_vao; QOpenGLPixelTransferOptions m_transferOptions; public: @@ -50,13 +49,14 @@ public: void resizeGL(int w, int h) override; void initializeGL() override; void paintGL() override; - void exposeEvent(QExposeEvent* event) override + void exposeEvent(QExposeEvent *event) override { onResize(size().width(), size().height()); } - std::vector> getBuffers() override; - HardwareRenderer(QWidget* parent = nullptr, RenderType rtype = RenderType::OpenGL) - : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()), QOpenGLFunctions() + std::vector> getBuffers() override; + HardwareRenderer(QWidget *parent = nullptr, RenderType rtype = RenderType::OpenGL) + : QOpenGLWindow(QOpenGLWindow::NoPartialUpdate, parent->windowHandle()) + , QOpenGLFunctions() { imagebufs[0] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); imagebufs[1] = std::unique_ptr(new uint8_t[2048 * 2048 * 4]); @@ -80,7 +80,8 @@ public: ~HardwareRenderer() { m_context->makeCurrent(this); - if (m_blt) m_blt->destroy(); + if (m_blt) + m_blt->destroy(); m_prog->release(); delete m_prog; m_prog = nullptr; @@ -88,7 +89,6 @@ public: delete m_context; } - void setRenderType(RenderType type); public slots: @@ -98,5 +98,5 @@ protected: std::array, 2> imagebufs; void resizeEvent(QResizeEvent *event) override; - bool event(QEvent* event) override; + bool event(QEvent *event) override; }; diff --git a/src/qt/qt_joystickconfiguration.cpp b/src/qt/qt_joystickconfiguration.cpp index 54aec5c6d..a9c53c07e 100644 --- a/src/qt/qt_joystickconfiguration.cpp +++ b/src/qt/qt_joystickconfiguration.cpp @@ -22,24 +22,23 @@ extern "C" { #include <86box/gameport.h> } - #include #include #include #include "qt_models_common.hpp" -JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) : - QDialog(parent), - ui(new Ui::JoystickConfiguration), - type(type), - joystick_nr(joystick_nr) +JoystickConfiguration::JoystickConfiguration(int type, int joystick_nr, QWidget *parent) + : QDialog(parent) + , ui(new Ui::JoystickConfiguration) + , type(type) + , joystick_nr(joystick_nr) { ui->setupUi(this); auto model = ui->comboBoxDevice->model(); Models::AddEntry(model, "None", 0); for (int c = 0; c < joysticks_present; c++) { - Models::AddEntry(model, plat_joystick_state[c].name, c+1); + Models::AddEntry(model, plat_joystick_state[c].name, c + 1); } ui->comboBoxDevice->setCurrentIndex(joystick_state[joystick_nr].plat_joystick_nr); @@ -51,35 +50,45 @@ JoystickConfiguration::~JoystickConfiguration() delete ui; } -int JoystickConfiguration::selectedDevice() { +int +JoystickConfiguration::selectedDevice() +{ return ui->comboBoxDevice->currentIndex(); } -int JoystickConfiguration::selectedAxis(int axis) { - auto* cbox = findChild(QString("cboxAxis%1").arg(QString::number(axis))); +int +JoystickConfiguration::selectedAxis(int axis) +{ + auto *cbox = findChild(QString("cboxAxis%1").arg(QString::number(axis))); if (cbox == nullptr) { return 0; } return cbox->currentIndex(); } -int JoystickConfiguration::selectedButton(int button) { - auto* cbox = findChild(QString("cboxButton%1").arg(QString::number(button))); +int +JoystickConfiguration::selectedButton(int button) +{ + auto *cbox = findChild(QString("cboxButton%1").arg(QString::number(button))); if (cbox == nullptr) { return 0; } return cbox->currentIndex(); } -int JoystickConfiguration::selectedPov(int pov) { - auto* cbox = findChild(QString("cboxPov%1").arg(QString::number(pov))); +int +JoystickConfiguration::selectedPov(int pov) +{ + auto *cbox = findChild(QString("cboxPov%1").arg(QString::number(pov))); if (cbox == nullptr) { return 0; } return cbox->currentIndex(); } -void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { +void +JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) +{ for (auto w : widgets) { ui->ct->removeWidget(w); w->deleteLater(); @@ -91,11 +100,11 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { } int joystick = index - 1; - int row = 0; + int row = 0; for (int c = 0; c < joystick_get_axis_count(type); c++) { /*Combo box*/ auto label = new QLabel(joystick_get_axis_name(type, c), this); - auto cbox = new QComboBox(this); + auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxAxis%1").arg(QString::number(c))); auto model = cbox->model(); @@ -135,7 +144,7 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { for (int c = 0; c < joystick_get_button_count(type); c++) { auto label = new QLabel(joystick_get_button_name(type, c), this); - auto cbox = new QComboBox(this); + auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxButton%1").arg(QString::number(c))); auto model = cbox->model(); @@ -155,11 +164,11 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { } for (int c = 0; c < joystick_get_pov_count(type) * 2; c++) { - QLabel* label; + QLabel *label; if (c & 1) { - label = new QLabel(QString("%1 (Y axis)").arg(joystick_get_pov_name(type, c/2)), this); + label = new QLabel(QString("%1 (Y axis)").arg(joystick_get_pov_name(type, c / 2)), this); } else { - label = new QLabel(QString("%1 (X axis)").arg(joystick_get_pov_name(type, c/2)), this); + label = new QLabel(QString("%1 (X axis)").arg(joystick_get_pov_name(type, c / 2)), this); } auto cbox = new QComboBox(this); cbox->setObjectName(QString("cboxPov%1").arg(QString::number(c))); @@ -179,17 +188,17 @@ void JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index) { if (mapping & POV_X) cbox->setCurrentIndex((mapping & 3) * 2); else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3)*2 + 1); + cbox->setCurrentIndex((mapping & 3) * 2 + 1); else cbox->setCurrentIndex(mapping + nr_povs * 2); mapping = joystick_state[joystick_nr].pov_mapping[c][1]; if (mapping & POV_X) - cbox->setCurrentIndex((mapping & 3)*2); + cbox->setCurrentIndex((mapping & 3) * 2); else if (mapping & POV_Y) - cbox->setCurrentIndex((mapping & 3)*2 + 1); + cbox->setCurrentIndex((mapping & 3) * 2 + 1); else - cbox->setCurrentIndex(mapping + nr_povs*2); + cbox->setCurrentIndex(mapping + nr_povs * 2); ui->ct->addWidget(label, row, 0); ui->ct->addWidget(cbox, row, 1); diff --git a/src/qt/qt_joystickconfiguration.hpp b/src/qt/qt_joystickconfiguration.hpp index b6882c52b..0b185ad73 100644 --- a/src/qt/qt_joystickconfiguration.hpp +++ b/src/qt/qt_joystickconfiguration.hpp @@ -7,8 +7,7 @@ namespace Ui { class JoystickConfiguration; } -class JoystickConfiguration : public QDialog -{ +class JoystickConfiguration : public QDialog { Q_OBJECT public: @@ -24,9 +23,9 @@ private slots: private: Ui::JoystickConfiguration *ui; - QList widgets; - int type; - int joystick_nr; + QList widgets; + int type; + int joystick_nr; }; #endif // QT_JOYSTICKCONFIGURATION_HPP diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index 9e93e882b..15aa51a7c 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -20,7 +20,7 @@ extern "C" { #define EMU_CPU_H // superhack - don't want timer.h to include cpu.h here, and some combo is preventing a compile -extern uint64_t tsc; +extern uint64_t tsc; #include <86box/hdd.h> #include <86box/timer.h> @@ -58,140 +58,154 @@ extern uint64_t tsc; #include -extern MainWindow* main_window; +extern MainWindow *main_window; namespace { - struct PixmapSetActive { - QPixmap normal; - QPixmap active; - void load(const QString& basePath); - }; - struct PixmapSetEmpty { - QPixmap normal; - QPixmap empty; - void load(const QString& basePath); - }; - struct PixmapSetEmptyActive { - QPixmap normal; - QPixmap active; - QPixmap empty; - QPixmap empty_active; - void load(QString basePath); - }; - struct Pixmaps { - PixmapSetEmpty cartridge; - PixmapSetEmptyActive cassette; - PixmapSetEmptyActive floppy_disabled; - PixmapSetEmptyActive floppy_525; - PixmapSetEmptyActive floppy_35; - PixmapSetEmptyActive cdrom; - PixmapSetEmptyActive zip; - PixmapSetEmptyActive mo; - PixmapSetActive hd; - PixmapSetEmptyActive net; - QPixmap sound; - }; +struct PixmapSetActive { + QPixmap normal; + QPixmap active; + void load(const QString &basePath); +}; +struct PixmapSetEmpty { + QPixmap normal; + QPixmap empty; + void load(const QString &basePath); +}; +struct PixmapSetEmptyActive { + QPixmap normal; + QPixmap active; + QPixmap empty; + QPixmap empty_active; + void load(QString basePath); +}; +struct Pixmaps { + PixmapSetEmpty cartridge; + PixmapSetEmptyActive cassette; + PixmapSetEmptyActive floppy_disabled; + PixmapSetEmptyActive floppy_525; + PixmapSetEmptyActive floppy_35; + PixmapSetEmptyActive cdrom; + PixmapSetEmptyActive zip; + PixmapSetEmptyActive mo; + PixmapSetActive hd; + PixmapSetEmptyActive net; + QPixmap sound; +}; - struct StateActive { - std::unique_ptr label; - PixmapSetActive* pixmaps = nullptr; - bool active = false; +struct StateActive { + std::unique_ptr label; + PixmapSetActive *pixmaps = nullptr; + bool active = false; - void setActive(bool b) { - if (!label || b == active) - return; - active = b; + void setActive(bool b) + { + if (!label || b == active) + return; + active = b; - refresh(); - } + refresh(); + } - void refresh() { - if (!label) - return; + void refresh() + { + if (!label) + return; + label->setPixmap(active ? pixmaps->active : pixmaps->normal); + } +}; +struct StateEmpty { + std::unique_ptr label; + PixmapSetEmpty *pixmaps = nullptr; + bool empty = false; + + void setEmpty(bool e) + { + if (!label || e == empty) + return; + empty = e; + + refresh(); + } + + void refresh() + { + if (!label) + return; + label->setPixmap(empty ? pixmaps->empty : pixmaps->normal); + } +}; +struct StateEmptyActive { + std::unique_ptr label; + PixmapSetEmptyActive *pixmaps = nullptr; + bool empty = false; + bool active = false; + + void setActive(bool b) + { + if (!label || b == active) + return; + + active = b; + refresh(); + } + void setEmpty(bool b) + { + if (!label || b == empty) + return; + + empty = b; + refresh(); + } + void refresh() + { + if (!label) + return; + if (empty) { + label->setPixmap(active ? pixmaps->empty_active : pixmaps->empty); + } else { label->setPixmap(active ? pixmaps->active : pixmaps->normal); } - }; - struct StateEmpty { - std::unique_ptr label; - PixmapSetEmpty* pixmaps = nullptr; - bool empty = false; - - void setEmpty(bool e) { - if (!label || e == empty) - return; - empty = e; - - refresh(); - } - - void refresh() { - if (!label) - return; - label->setPixmap(empty ? pixmaps->empty : pixmaps->normal); - } - }; - struct StateEmptyActive { - std::unique_ptr label; - PixmapSetEmptyActive* pixmaps = nullptr; - bool empty = false; - bool active = false; - - void setActive(bool b) { - if (!label || b == active) - return; - - active = b; - refresh(); - } - void setEmpty(bool b) { - if (!label || b == empty) - return; - - empty = b; - refresh(); - } - void refresh() { - if (!label) - return; - if (empty) { - label->setPixmap(active ? pixmaps->empty_active : pixmaps->empty); - } else { - label->setPixmap(active ? pixmaps->active : pixmaps->normal); - } - } - }; - - static QSize pixmap_size(16, 16); - static const QString pixmap_empty = QStringLiteral("_empty"); - static const QString pixmap_active = QStringLiteral("_active"); - static const QString pixmap_empty_active = QStringLiteral("_empty_active"); - void PixmapSetEmpty::load(const QString &basePath) { - normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); - empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); } +}; - void PixmapSetActive::load(const QString &basePath) { - normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); - active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); - } +static QSize pixmap_size(16, 16); +static const QString pixmap_empty = QStringLiteral("_empty"); +static const QString pixmap_active = QStringLiteral("_active"); +static const QString pixmap_empty_active = QStringLiteral("_empty_active"); +void +PixmapSetEmpty::load(const QString &basePath) +{ + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); +} - void PixmapSetEmptyActive::load(QString basePath) { - normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); - active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); - empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); - empty_active = ProgSettings::loadIcon(basePath.arg(pixmap_empty_active)).pixmap(pixmap_size); - } +void +PixmapSetActive::load(const QString &basePath) +{ + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); +} + +void +PixmapSetEmptyActive::load(QString basePath) +{ + normal = ProgSettings::loadIcon(basePath.arg(QStringLiteral(""))).pixmap(pixmap_size); + active = ProgSettings::loadIcon(basePath.arg(pixmap_active)).pixmap(pixmap_size); + empty = ProgSettings::loadIcon(basePath.arg(pixmap_empty)).pixmap(pixmap_size); + empty_active = ProgSettings::loadIcon(basePath.arg(pixmap_empty_active)).pixmap(pixmap_size); +} } struct MachineStatus::States { Pixmaps pixmaps; - States(QObject* parent) { + States(QObject *parent) + { pixmaps.cartridge.load("/cartridge%1.ico"); pixmaps.cassette.load("/cassette%1.ico"); - pixmaps.floppy_disabled.normal = ProgSettings::loadIcon(QStringLiteral("/floppy_disabled.ico")).pixmap(pixmap_size); - pixmaps.floppy_disabled.active = pixmaps.floppy_disabled.normal; - pixmaps.floppy_disabled.empty = pixmaps.floppy_disabled.normal; + pixmaps.floppy_disabled.normal = ProgSettings::loadIcon(QStringLiteral("/floppy_disabled.ico")).pixmap(pixmap_size); + pixmaps.floppy_disabled.active = pixmaps.floppy_disabled.normal; + pixmaps.floppy_disabled.empty = pixmaps.floppy_disabled.normal; pixmaps.floppy_disabled.empty_active = pixmaps.floppy_disabled.normal; pixmaps.floppy_525.load("/floppy_525%1.ico"); pixmaps.floppy_35.load("/floppy_35%1.ico"); @@ -204,42 +218,42 @@ struct MachineStatus::States { cartridge[0].pixmaps = &pixmaps.cartridge; cartridge[1].pixmaps = &pixmaps.cartridge; - cassette.pixmaps = &pixmaps.cassette; - for (auto& f : fdd) { + cassette.pixmaps = &pixmaps.cassette; + for (auto &f : fdd) { f.pixmaps = &pixmaps.floppy_disabled; } - for (auto& c : cdrom) { + for (auto &c : cdrom) { c.pixmaps = &pixmaps.cdrom; } - for (auto& z : zip) { + for (auto &z : zip) { z.pixmaps = &pixmaps.zip; } - for (auto& m : mo) { + for (auto &m : mo) { m.pixmaps = &pixmaps.mo; } - for (auto& h : hdds) { + for (auto &h : hdds) { h.pixmaps = &pixmaps.hd; } - for (auto& n : net) { + for (auto &n : net) { n.pixmaps = &pixmaps.net; } } - std::array cartridge; - StateEmptyActive cassette; - std::array fdd; - std::array cdrom; - std::array zip; - std::array mo; - std::array hdds; + std::array cartridge; + StateEmptyActive cassette; + std::array fdd; + std::array cdrom; + std::array zip; + std::array mo; + std::array hdds; std::array net; - std::unique_ptr sound; - std::unique_ptr text; + std::unique_ptr sound; + std::unique_ptr text; }; -MachineStatus::MachineStatus(QObject *parent) : - QObject(parent), - refreshTimer(new QTimer(this)) +MachineStatus::MachineStatus(QObject *parent) + : QObject(parent) + , refreshTimer(new QTimer(this)) { d = std::make_unique(this); connect(refreshTimer, &QTimer::timeout, this, &MachineStatus::refreshIcons); @@ -248,19 +262,27 @@ MachineStatus::MachineStatus(QObject *parent) : MachineStatus::~MachineStatus() = default; -bool MachineStatus::hasCassette() { +bool +MachineStatus::hasCassette() +{ return cassette_enable > 0 ? true : false; } -bool MachineStatus::hasIDE() { +bool +MachineStatus::hasIDE() +{ return machine_has_flags(machine, MACHINE_IDE_QUAD) > 0; } -bool MachineStatus::hasSCSI() { +bool +MachineStatus::hasSCSI() +{ return machine_has_flags(machine, MACHINE_SCSI_DUAL) > 0; } -void MachineStatus::iterateFDD(const std::function &cb) { +void +MachineStatus::iterateFDD(const std::function &cb) +{ for (int i = 0; i < FDD_NUM; ++i) { if (fdd_get_type(i) != 0) { cb(i); @@ -268,17 +290,15 @@ void MachineStatus::iterateFDD(const std::function &cb) { } } -void MachineStatus::iterateCDROM(const std::function &cb) { +void +MachineStatus::iterateCDROM(const std::function &cb) +{ auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < CDROM_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && - !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && - hdc_name.left(5) != QStringLiteral("xtide")) + if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) continue; - if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && - (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && - (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((cdrom[i].bus_type == CDROM_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (cdrom[i].bus_type != 0) { cb(i); @@ -286,17 +306,15 @@ void MachineStatus::iterateCDROM(const std::function &cb) { } } -void MachineStatus::iterateZIP(const std::function &cb) { +void +MachineStatus::iterateZIP(const std::function &cb) +{ auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < ZIP_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && - !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && - hdc_name.left(5) != QStringLiteral("xtide")) + if ((zip_drives[i].bus_type == ZIP_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) continue; - if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && - (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && - (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((zip_drives[i].bus_type == ZIP_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (zip_drives[i].bus_type != 0) { cb(i); @@ -304,17 +322,15 @@ void MachineStatus::iterateZIP(const std::function &cb) { } } -void MachineStatus::iterateMO(const std::function &cb) { +void +MachineStatus::iterateMO(const std::function &cb) +{ auto hdc_name = QString(hdc_get_internal_name(hdc_current)); for (size_t i = 0; i < MO_NUM; i++) { /* Could be Internal or External IDE.. */ - if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && - !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && - hdc_name.left(5) != QStringLiteral("xtide")) + if ((mo_drives[i].bus_type == MO_BUS_ATAPI) && !hasIDE() && hdc_name.left(3) != QStringLiteral("ide") && hdc_name.left(5) != QStringLiteral("xtide")) continue; - if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && - (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && - (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) + if ((mo_drives[i].bus_type == MO_BUS_SCSI) && !hasSCSI() && (scsi_card_current[0] == 0) && (scsi_card_current[1] == 0) && (scsi_card_current[2] == 0) && (scsi_card_current[3] == 0)) continue; if (mo_drives[i].bus_type != 0) { cb(i); @@ -322,7 +338,9 @@ void MachineStatus::iterateMO(const std::function &cb) { } } -void MachineStatus::iterateNIC(const std::function &cb) { +void +MachineStatus::iterateNIC(const std::function &cb) +{ for (int i = 0; i < NET_CARD_MAX; i++) { if (network_dev_available(i)) { cb(i); @@ -330,7 +348,9 @@ void MachineStatus::iterateNIC(const std::function &cb) { } } -static int hdd_count(int bus) { +static int +hdd_count(int bus) +{ int c = 0; int i; @@ -340,10 +360,12 @@ static int hdd_count(int bus) { } } - return(c); + return (c); } -void MachineStatus::refreshIcons() { +void +MachineStatus::refreshIcons() +{ for (size_t i = 0; i < FDD_NUM; ++i) { d->fdd[i].setActive(machine_status.fdd[i].active); d->fdd[i].setEmpty(machine_status.fdd[i].empty); @@ -375,18 +397,19 @@ void MachineStatus::refreshIcons() { for (int i = 0; i < 2; ++i) { d->cartridge[i].setEmpty(machine_status.cartridge[i].empty); } - } -void MachineStatus::refresh(QStatusBar* sbar) { - bool has_mfm = machine_has_flags(machine, MACHINE_MFM) > 0; - bool has_xta = machine_has_flags(machine, MACHINE_XTA) > 0; +void +MachineStatus::refresh(QStatusBar *sbar) +{ + bool has_mfm = machine_has_flags(machine, MACHINE_MFM) > 0; + bool has_xta = machine_has_flags(machine, MACHINE_XTA) > 0; bool has_esdi = machine_has_flags(machine, MACHINE_ESDI) > 0; - int c_mfm = hdd_count(HDD_BUS_MFM); + int c_mfm = hdd_count(HDD_BUS_MFM); int c_esdi = hdd_count(HDD_BUS_ESDI); - int c_xta = hdd_count(HDD_BUS_XTA); - int c_ide = hdd_count(HDD_BUS_IDE); + int c_xta = hdd_count(HDD_BUS_XTA); + int c_ide = hdd_count(HDD_BUS_IDE); int c_scsi = hdd_count(HDD_BUS_SCSI); sbar->removeWidget(d->cassette.label.get()); @@ -417,10 +440,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->cassette.label = std::make_unique(); d->cassette.setEmpty(QString(cassette_fname).isEmpty()); d->cassette.refresh(); - connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) { + connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::clicked, [](QPoint pos) { MediaMenu::ptr->cassetteMenu->popup(pos - QPoint(0, MediaMenu::ptr->cassetteMenu->sizeHint().height())); }); - connect((ClickableLabel*)d->cassette.label.get(), &ClickableLabel::dropped, [](QString str) { + connect((ClickableLabel *) d->cassette.label.get(), &ClickableLabel::dropped, [](QString str) { MediaMenu::ptr->cassetteMount(str, false); }); d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); @@ -433,10 +456,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->cartridge[i].label = std::make_unique(); d->cartridge[i].setEmpty(QString(cart_fns[i]).isEmpty()); d->cartridge[i].refresh(); - connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->cartridge[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->cartridgeMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cartridgeMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->cartridge[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->cartridge[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->cartridgeMount(i, str); }); d->cartridge[i].label->setToolTip(MediaMenu::ptr->cartridgeMenus[i]->title()); @@ -458,10 +481,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->fdd[i].setEmpty(QString(floppyfns[i]).isEmpty()); d->fdd[i].setActive(false); d->fdd[i].refresh(); - connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->fdd[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->floppyMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->floppyMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->fdd[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->fdd[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->floppyMount(i, str, false); }); d->fdd[i].label->setToolTip(MediaMenu::ptr->floppyMenus[i]->title()); @@ -474,10 +497,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->cdrom[i].setEmpty(cdrom[i].host_drive != 200 || QString(cdrom[i].image_path).isEmpty()); d->cdrom[i].setActive(false); d->cdrom[i].refresh(); - connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->cdromMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->cdromMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->cdrom[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->cdrom[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->cdromMount(i, str); }); d->cdrom[i].label->setToolTip(MediaMenu::ptr->cdromMenus[i]->title()); @@ -490,10 +513,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->zip[i].setEmpty(QString(zip_drives[i].image_path).isEmpty()); d->zip[i].setActive(false); d->zip[i].refresh(); - connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->zipMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->zipMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->zip[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->zip[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->zipMount(i, str, false); }); d->zip[i].label->setToolTip(MediaMenu::ptr->zipMenus[i]->title()); @@ -506,10 +529,10 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->mo[i].setEmpty(QString(mo_drives[i].image_path).isEmpty()); d->mo[i].setActive(false); d->mo[i].refresh(); - connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->mo[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->moMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->moMenus[i]->sizeHint().height())); }); - connect((ClickableLabel*)d->mo[i].label.get(), &ClickableLabel::dropped, [i](QString str) { + connect((ClickableLabel *) d->mo[i].label.get(), &ClickableLabel::dropped, [i](QString str) { MediaMenu::ptr->moMount(i, str, false); }); d->mo[i].label->setToolTip(MediaMenu::ptr->moMenus[i]->title()); @@ -523,7 +546,7 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->net[i].setActive(false); d->net[i].refresh(); d->net[i].label->setToolTip(MediaMenu::ptr->netMenus[i]->title()); - connect((ClickableLabel*)d->net[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + connect((ClickableLabel *) d->net[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { MediaMenu::ptr->netMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->netMenus[i]->sizeHint().height())); }); sbar->addWidget(d->net[i].label.get()); @@ -558,8 +581,7 @@ void MachineStatus::refresh(QStatusBar* sbar) { d->hdds[HDD_BUS_IDE].label->setToolTip(tr("Hard disk (%s)").replace("%s", "IDE")); sbar->addWidget(d->hdds[HDD_BUS_IDE].label.get()); } - if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || - (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { + if ((hasSCSI() || (scsi_card_current[0] != 0) || (scsi_card_current[1] != 0) || (scsi_card_current[2] != 0) || (scsi_card_current[3] != 0)) && c_scsi > 0) { d->hdds[HDD_BUS_SCSI].label = std::make_unique(); d->hdds[HDD_BUS_SCSI].setActive(false); d->hdds[HDD_BUS_SCSI].refresh(); @@ -580,45 +602,57 @@ void MachineStatus::refresh(QStatusBar* sbar) { sbar->addWidget(d->text.get()); } -void MachineStatus::message(const QString &msg) { +void +MachineStatus::message(const QString &msg) +{ d->text->setText(msg); } -QString MachineStatus::getMessage() { +QString +MachineStatus::getMessage() +{ return d->text->text(); } -void MachineStatus::updateTip(int tag) +void +MachineStatus::updateTip(int tag) { int category = tag & 0xfffffff0; - int item = tag & 0xf; - if (!MediaMenu::ptr) return; + int item = tag & 0xf; + if (!MediaMenu::ptr) + return; switch (category) { - case SB_CASSETTE: - if (d->cassette.label && MediaMenu::ptr->cassetteMenu) d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); - break; - case SB_CARTRIDGE: - if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); - break; - case SB_FLOPPY: - if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); - break; - case SB_CDROM: - if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); - break; - case SB_ZIP: - if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); - break; - case SB_MO: - if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); - break; - case SB_HDD: - break; - case SB_NETWORK: - break; - case SB_SOUND: - break; - case SB_TEXT: - break; + case SB_CASSETTE: + if (d->cassette.label && MediaMenu::ptr->cassetteMenu) + d->cassette.label->setToolTip(MediaMenu::ptr->cassetteMenu->title()); + break; + case SB_CARTRIDGE: + if (d->cartridge[item].label && MediaMenu::ptr->cartridgeMenus[item]) + d->cartridge[item].label->setToolTip(MediaMenu::ptr->cartridgeMenus[item]->title()); + break; + case SB_FLOPPY: + if (d->fdd[item].label && MediaMenu::ptr->floppyMenus[item]) + d->fdd[item].label->setToolTip(MediaMenu::ptr->floppyMenus[item]->title()); + break; + case SB_CDROM: + if (d->cdrom[item].label && MediaMenu::ptr->cdromMenus[item]) + d->cdrom[item].label->setToolTip(MediaMenu::ptr->cdromMenus[item]->title()); + break; + case SB_ZIP: + if (d->zip[item].label && MediaMenu::ptr->zipMenus[item]) + d->zip[item].label->setToolTip(MediaMenu::ptr->zipMenus[item]->title()); + break; + case SB_MO: + if (d->mo[item].label && MediaMenu::ptr->moMenus[item]) + d->mo[item].label->setToolTip(MediaMenu::ptr->moMenus[item]->title()); + break; + case SB_HDD: + break; + case SB_NETWORK: + break; + case SB_SOUND: + break; + case SB_TEXT: + break; } } diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index 8d085f93a..c2e51819a 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -12,47 +12,48 @@ class QStatusBar; class ClickableLabel : public QLabel { Q_OBJECT; - public: - explicit ClickableLabel(QWidget* parent = nullptr) - : QLabel(parent) {} - ~ClickableLabel() {}; - signals: - void clicked(QPoint); - void doubleClicked(QPoint); - void dropped(QString); +public: + explicit ClickableLabel(QWidget *parent = nullptr) + : QLabel(parent) + { + } + ~ClickableLabel() {}; - protected: - void mousePressEvent(QMouseEvent* event) override { emit clicked(event->globalPos()); } - void mouseDoubleClickEvent(QMouseEvent* event) override { emit doubleClicked(event->globalPos()); } - void dragEnterEvent(QDragEnterEvent* event) override - { - if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { - event->setDropAction(Qt::CopyAction); - event->acceptProposedAction(); - } - else event->ignore(); - } - void dragMoveEvent(QDragMoveEvent* event) override - { - if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { - event->setDropAction(Qt::CopyAction); - event->acceptProposedAction(); - } - else event->ignore(); - } - void dropEvent(QDropEvent* event) override - { - if (event->dropAction() == Qt::CopyAction) - { - emit dropped(event->mimeData()->urls()[0].toLocalFile()); - } - else event->ignore(); - } +signals: + void clicked(QPoint); + void doubleClicked(QPoint); + void dropped(QString); + +protected: + void mousePressEvent(QMouseEvent *event) override { emit clicked(event->globalPos()); } + void mouseDoubleClickEvent(QMouseEvent *event) override { emit doubleClicked(event->globalPos()); } + void dragEnterEvent(QDragEnterEvent *event) override + { + if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { + event->setDropAction(Qt::CopyAction); + event->acceptProposedAction(); + } else + event->ignore(); + } + void dragMoveEvent(QDragMoveEvent *event) override + { + if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) { + event->setDropAction(Qt::CopyAction); + event->acceptProposedAction(); + } else + event->ignore(); + } + void dropEvent(QDropEvent *event) override + { + if (event->dropAction() == Qt::CopyAction) { + emit dropped(event->mimeData()->urls()[0].toLocalFile()); + } else + event->ignore(); + } }; -class MachineStatus : public QObject -{ +class MachineStatus : public QObject { Q_OBJECT public: @@ -62,23 +63,23 @@ public: static bool hasCassette(); static bool hasIDE(); static bool hasSCSI(); - static void iterateFDD(const std::function& cb); - static void iterateCDROM(const std::function& cb); - static void iterateZIP(const std::function& cb); - static void iterateMO(const std::function& cb); - static void iterateNIC(const std::function& cb); + static void iterateFDD(const std::function &cb); + static void iterateCDROM(const std::function &cb); + static void iterateZIP(const std::function &cb); + static void iterateMO(const std::function &cb); + static void iterateNIC(const std::function &cb); QString getMessage(); public slots: - void refresh(QStatusBar* sbar); - void message(const QString& msg); + void refresh(QStatusBar *sbar); + void message(const QString &msg); void updateTip(int tag); void refreshIcons(); private: struct States; std::unique_ptr d; - QTimer *refreshTimer; + QTimer *refreshTimer; }; #endif // QT_MACHINESTATUS_HPP diff --git a/src/qt/qt_main.cpp b/src/qt/qt_main.cpp index 5be64050a..1ae545227 100644 --- a/src/qt/qt_main.cpp +++ b/src/qt/qt_main.cpp @@ -31,23 +31,22 @@ #ifdef QT_STATIC /* Static builds need plugin imports */ -#include +# include Q_IMPORT_PLUGIN(QICOPlugin) -#ifdef Q_OS_WINDOWS +# ifdef Q_OS_WINDOWS Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin) -#endif +# endif #endif #ifdef Q_OS_WINDOWS -#include "qt_winrawinputfilter.hpp" -#include "qt_winmanagerfilter.hpp" -#include <86box/win.h> -#include +# include "qt_winrawinputfilter.hpp" +# include "qt_winmanagerfilter.hpp" +# include <86box/win.h> +# include #endif -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/config.h> #include <86box/plat.h> @@ -69,15 +68,15 @@ extern "C" #include "qt_unixmanagerfilter.hpp" // Void Cast -#define VC(x) const_cast(x) +#define VC(x) const_cast(x) extern QElapsedTimer elapsed_timer; -extern MainWindow* main_window; +extern MainWindow *main_window; extern "C" { #include <86box/timer.h> #include <86box/nvr.h> - extern int qt_nvr_save(void); +extern int qt_nvr_save(void); } void qt_set_sequence_auto_mnemonic(bool b); @@ -86,11 +85,11 @@ void main_thread_fn() { uint64_t old_time, new_time; - int drawits, frames; + int drawits, frames; QThread::currentThread()->setPriority(QThread::HighestPriority); framecountx = 0; - //title_update = 1; + // title_update = 1; old_time = elapsed_timer.elapsed(); drawits = frames = 0; while (!is_quit && cpu_thread_run) { @@ -98,10 +97,10 @@ main_thread_fn() new_time = elapsed_timer.elapsed(); #ifdef USE_GDBSTUB if (gdbstub_next_asap && (drawits <= 0)) - drawits = 10; + drawits = 10; else #endif - drawits += (new_time - old_time); + drawits += (new_time - old_time); old_time = new_time; if (drawits > 0 && !dopause) { /* Yes, so do one frame now. */ @@ -117,8 +116,8 @@ main_thread_fn() #ifdef USE_INSTRUMENT if (instru_enabled) { - uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; - uint64_t total_elapsed_ms = (uint64_t)((double)tsc / cpu_s->rspeed * 1000); + uint64_t elapsed_us = (elapsed_timer.nsecsElapsed() - start_time) / 1000; + uint64_t total_elapsed_ms = (uint64_t) ((double) tsc / cpu_s->rspeed * 1000); printf("[instrument] %llu, %llu\n", total_elapsed_ms, elapsed_us); if (instru_run_ms && total_elapsed_ms >= instru_run_ms) break; @@ -128,7 +127,7 @@ main_thread_fn() if (++frames >= 200 && nvr_dosave) { qt_nvr_save(); nvr_dosave = 0; - frames = 0; + frames = 0; } } else { /* Just so we dont overload the host OS. */ @@ -137,12 +136,14 @@ main_thread_fn() } is_quit = 1; - QTimer::singleShot(0, QApplication::instance(), [] () { QApplication::instance()->quit(); }); + QTimer::singleShot(0, QApplication::instance(), []() { QApplication::instance()->quit(); }); } -static std::thread* main_thread; +static std::thread *main_thread; -int main(int argc, char* argv[]) { +int +main(int argc, char *argv[]) +{ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QApplication::setAttribute(Qt::AA_DisableHighDpiScaling, false); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); @@ -168,8 +169,7 @@ int main(int argc, char* argv[]) { #endif elapsed_timer.start(); - if (!pc_init(argc, argv)) - { + if (!pc_init(argc, argv)) { return 0; } @@ -182,16 +182,14 @@ int main(int argc, char* argv[]) { QApplication::setFont(QFont(font_name, font_size.toInt())); SetCurrentProcessExplicitAppUserModelID(L"86Box.86Box"); #endif - if (! pc_init_modules()) { - ui_msgbox_header(MBX_FATAL, (void*)IDS_2121, (void*)IDS_2056); + if (!pc_init_modules()) { + ui_msgbox_header(MBX_FATAL, (void *) IDS_2121, (void *) IDS_2056); return 6; } - if (settings_only) - { + if (settings_only) { Settings settings; - if (settings.exec() == QDialog::Accepted) - { + if (settings.exec() == QDialog::Accepted) { settings.save(); config_save(); } @@ -212,22 +210,21 @@ int main(int argc, char* argv[]) { #ifdef Q_OS_WINDOWS /* Setup VM-manager messages */ std::unique_ptr wmfilter; - if (source_hwnd) - { - HWND main_hwnd = (HWND)main_window->winId(); + if (source_hwnd) { + HWND main_hwnd = (HWND) main_window->winId(); wmfilter.reset(new WindowsManagerFilter()); QObject::connect(wmfilter.get(), &WindowsManagerFilter::showsettings, main_window, &MainWindow::showSettings); QObject::connect(wmfilter.get(), &WindowsManagerFilter::pause, main_window, &MainWindow::togglePause); QObject::connect(wmfilter.get(), &WindowsManagerFilter::reset, main_window, &MainWindow::hardReset); QObject::connect(wmfilter.get(), &WindowsManagerFilter::request_shutdown, main_window, &MainWindow::close); - QObject::connect(wmfilter.get(), &WindowsManagerFilter::force_shutdown, [](){ + QObject::connect(wmfilter.get(), &WindowsManagerFilter::force_shutdown, []() { do_stop(); emit main_window->close(); }); - QObject::connect(wmfilter.get(), &WindowsManagerFilter::ctrlaltdel, [](){ pc_send_cad(); }); - QObject::connect(wmfilter.get(), &WindowsManagerFilter::dialogstatus, [main_hwnd](bool open){ - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDDLGSTATUS, (WPARAM)(open ? 1 : 0), (LPARAM)main_hwnd); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::ctrlaltdel, []() { pc_send_cad(); }); + QObject::connect(wmfilter.get(), &WindowsManagerFilter::dialogstatus, [main_hwnd](bool open) { + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) (open ? 1 : 0), (LPARAM) main_hwnd); }); /* Native filter to catch VM-managers commands */ @@ -237,41 +234,39 @@ int main(int argc, char* argv[]) { main_window->installEventFilter(wmfilter.get()); /* Send main window HWND to manager */ - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDHWND, (WPARAM)unique_id, (LPARAM)main_hwnd); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDHWND, (WPARAM) unique_id, (LPARAM) main_hwnd); /* Send shutdown message to manager */ - QObject::connect(&app, &QApplication::destroyed, [main_hwnd](QObject*) { - PostMessage((HWND)(uintptr_t)source_hwnd, WM_HAS_SHUTDOWN, (WPARAM)0, (LPARAM)main_hwnd); + QObject::connect(&app, &QApplication::destroyed, [main_hwnd](QObject *) { + PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) main_hwnd); }); } /* Setup raw input */ auto rawInputFilter = WindowsRawInputFilter::Register(main_window); - if (rawInputFilter) - { + if (rawInputFilter) { app.installNativeEventFilter(rawInputFilter.get()); QObject::disconnect(main_window, &MainWindow::pollMouse, 0, 0); - QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter*)rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection); + QObject::connect(main_window, &MainWindow::pollMouse, (WindowsRawInputFilter *) rawInputFilter.get(), &WindowsRawInputFilter::mousePoll, Qt::DirectConnection); main_window->setSendKeyboardInput(false); } #endif UnixManagerSocket socket; - if (qgetenv("86BOX_MANAGER_SOCKET").size()) - { + if (qgetenv("86BOX_MANAGER_SOCKET").size()) { QObject::connect(&socket, &UnixManagerSocket::showsettings, main_window, &MainWindow::showSettings); QObject::connect(&socket, &UnixManagerSocket::pause, main_window, &MainWindow::togglePause); QObject::connect(&socket, &UnixManagerSocket::resetVM, main_window, &MainWindow::hardReset); QObject::connect(&socket, &UnixManagerSocket::request_shutdown, main_window, &MainWindow::close); - QObject::connect(&socket, &UnixManagerSocket::force_shutdown, [](){ + QObject::connect(&socket, &UnixManagerSocket::force_shutdown, []() { do_stop(); emit main_window->close(); }); - QObject::connect(&socket, &UnixManagerSocket::ctrlaltdel, [](){ pc_send_cad(); }); + QObject::connect(&socket, &UnixManagerSocket::ctrlaltdel, []() { pc_send_cad(); }); main_window->installEventFilter(&socket); socket.connectToServer(qgetenv("86BOX_MANAGER_SOCKET")); } - //pc_reset_hard_init(); + // pc_reset_hard_init(); /* Set the PAUSE mode depending on the renderer. */ // plat_pause(0); @@ -297,13 +292,12 @@ int main(int argc, char* argv[]) { } /* Initialize the rendering window, or fullscreen. */ - QTimer::singleShot(0, &app, [] - { + QTimer::singleShot(0, &app, [] { pc_reset_hard_init(); main_thread = new std::thread(main_thread_fn); }); - auto ret = app.exec(); + auto ret = app.exec(); cpu_thread_run = 0; main_thread->join(); pc_close(nullptr); diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 7b3e03f86..bf3ef4014 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -47,13 +47,13 @@ extern "C" { #include <86box/version.h> #ifdef USE_VNC -#include <86box/vnc.h> +# include <86box/vnc.h> #endif - extern int qt_nvr_save(void); +extern int qt_nvr_save(void); #ifdef MTR_ENABLED -#include +# include #endif }; @@ -76,8 +76,8 @@ extern "C" { #include #include #if QT_CONFIG(vulkan) -#include -#include +# include +# include #endif #include @@ -89,70 +89,69 @@ extern "C" { #include "qt_util.hpp" #if defined __unix__ && !defined __HAIKU__ -#ifdef WAYLAND -#include "wl_mouse.hpp" -#endif -#include -#include -#undef KeyPress -#undef KeyRelease +# ifdef WAYLAND +# include "wl_mouse.hpp" +# endif +# include +# include +# undef KeyPress +# undef KeyRelease #endif #ifdef Q_OS_MACOS // The namespace is required to avoid clashing typedefs; we only use this // header for its #defines anyway. namespace IOKit { - #include +# include } #endif #ifdef __HAIKU__ -#include -#include +# include +# include -extern MainWindow* main_window; +extern MainWindow *main_window; -filter_result keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) +filter_result +keyb_filter(BMessage *message, BHandler **target, BMessageFilter *filter) { if (message->what == B_KEY_DOWN || message->what == B_KEY_UP - || message->what == B_UNMAPPED_KEY_DOWN || message->what == B_UNMAPPED_KEY_UP) - { + || message->what == B_UNMAPPED_KEY_DOWN || message->what == B_UNMAPPED_KEY_UP) { int key_state = 0, key_scancode = 0; key_state = message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN; message->FindInt32("key", &key_scancode); QGuiApplication::postEvent(main_window, new QKeyEvent(key_state ? QEvent::KeyPress : QEvent::KeyRelease, 0, QGuiApplication::keyboardModifiers(), key_scancode, 0, 0)); - if (key_scancode == 0x68 && key_state) - { + if (key_scancode == 0x68 && key_state) { QGuiApplication::postEvent(main_window, new QKeyEvent(QEvent::KeyRelease, 0, QGuiApplication::keyboardModifiers(), key_scancode, 0, 0)); } } return B_DISPATCH_MESSAGE; } -static BMessageFilter* filter; +static BMessageFilter *filter; #endif -std::atomic blitDummied{false}; +std::atomic blitDummied { false }; -extern void qt_mouse_capture(int); +extern void qt_mouse_capture(int); extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index); -extern MainWindow* main_window; +extern MainWindow *main_window; -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - ui(new Ui::MainWindow) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) { - mm = std::make_shared(this); + mm = std::make_shared(this); MediaMenu::ptr = mm; - status = std::make_unique(this); + status = std::make_unique(this); #ifdef __HAIKU__ filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE, keyb_filter); - ((BWindow*)this->winId())->AddFilter(filter); + ((BWindow *) this->winId())->AddFilter(filter); #endif setUnifiedTitleAndToolBarOnMac(true); - extern MainWindow* main_window; + extern MainWindow *main_window; main_window = this; ui->setupUi(this); ui->stackedWidget->setMouseTracking(true); @@ -184,14 +183,14 @@ MainWindow::MainWindow(QWidget *parent) : this->setWindowFlag(Qt::WindowMaximizeButtonHint, vid_resize == 1); QString vmname(vm_name); - if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') vmname.truncate(vmname.size() - 1); + if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') + vmname.truncate(vmname.size() - 1); this->setWindowTitle(QString("%1 - %2 %3").arg(vmname, EMU_NAME, EMU_VERSION_FULL)); connect(this, &MainWindow::showMessageForNonQtThread, this, &MainWindow::showMessage_, Qt::BlockingQueuedConnection); - connect(this, &MainWindow::setTitle, this, [this,toolbar_label](const QString& title) { - if (dopause && !hide_tool_bar) - { + connect(this, &MainWindow::setTitle, this, [this, toolbar_label](const QString &title) { + if (dopause && !hide_tool_bar) { toolbar_label->setText(toolbar_label->text() + tr(" - PAUSED")); return; } @@ -250,7 +249,8 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::resizeContents, this, [this](int w, int h) { if (shownonce) { - if (resizableonce == false) ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (resizableonce == false) + ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); resizableonce = true; } if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { @@ -266,8 +266,7 @@ MainWindow::MainWindow(QWidget *parent) : } }); - connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) - { + connect(this, &MainWindow::resizeContentsMonitor, this, [this](int w, int h, int monitor_index) { if (!QApplication::platformName().contains("eglfs") && vid_resize != 1) { qDebug() << "Resize"; w = (w / (!dpi_scale ? util::screenOfWidget(renderers[monitor_index].get())->devicePixelRatio() : 1.)); @@ -280,8 +279,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(ui->menubar, &QMenuBar::triggered, this, [this] { config_save(); - if (QApplication::activeWindow() == this) - { + if (QApplication::activeWindow() == this) { ui->stackedWidget->setFocusRenderer(); } }); @@ -309,13 +307,16 @@ MainWindow::MainWindow(QWidget *parent) : #if defined Q_OS_WINDOWS || defined Q_OS_MACOS /* Make the option visible only if ANGLE is loaded. */ ui->actionHardware_Renderer_OpenGL_ES->setVisible(QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) vid_api = 1; + if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES && vid_api == 2) + vid_api = 1; #endif ui->actionHardware_Renderer_OpenGL->setVisible(QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES); - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) vid_api = 0; + if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES && vid_api == 1) + vid_api = 0; if ((QApplication::platformName().contains("eglfs") || QApplication::platformName() == "haiku")) { - if (vid_api >= 1) fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); + if (vid_api >= 1) + fprintf(stderr, "OpenGL renderers are unsupported on %s.\n", QApplication::platformName().toUtf8().data()); vid_api = 0; ui->actionHardware_Renderer_OpenGL->setVisible(false); ui->actionHardware_Renderer_OpenGL_ES->setVisible(false); @@ -324,11 +325,13 @@ MainWindow::MainWindow(QWidget *parent) : } #if !defined Q_OS_WINDOWS ui->actionDirect3D_9->setVisible(false); - if (vid_api == 5) vid_api = 0; + if (vid_api == 5) + vid_api = 0; #endif #ifndef USE_VNC - if (vid_api == 6) vid_api = 0; + if (vid_api == 6) + vid_api = 0; ui->actionVNC->setVisible(false); #endif @@ -348,11 +351,12 @@ MainWindow::MainWindow(QWidget *parent) : if (!vulkanAvailable) #endif { - if (vid_api == 4) vid_api = 0; + if (vid_api == 4) + vid_api = 0; ui->actionVulkan->setVisible(false); } - QActionGroup* actGroup = nullptr; + QActionGroup *actGroup = nullptr; actGroup = new QActionGroup(this); actGroup->addAction(ui->actionSoftware_Renderer); @@ -364,7 +368,7 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionVNC); actGroup->setExclusive(true); - connect(actGroup, &QActionGroup::triggered, [this](QAction* action) { + connect(actGroup, &QActionGroup::triggered, [this](QAction *action) { vid_api = action->property("vid_api").toInt(); #ifdef USE_VNC if (vnc_enabled && vid_api != 6) { @@ -376,40 +380,41 @@ MainWindow::MainWindow(QWidget *parent) : } #endif RendererStack::Renderer newVidApi = RendererStack::Renderer::Software; - switch (vid_api) - { - case 0: - newVidApi = RendererStack::Renderer::Software; - break; - case 1: - newVidApi = (RendererStack::Renderer::OpenGL); - break; - case 2: - newVidApi = (RendererStack::Renderer::OpenGLES); - break; - case 3: - newVidApi = (RendererStack::Renderer::OpenGL3); - break; - case 4: - newVidApi = (RendererStack::Renderer::Vulkan); - break; - case 5: - newVidApi = (RendererStack::Renderer::Direct3D9); - break; -#ifdef USE_VNC - case 6: - { + switch (vid_api) { + case 0: newVidApi = RendererStack::Renderer::Software; - startblit(); - vnc_enabled = vnc_init(nullptr); - endblit(); - } + break; + case 1: + newVidApi = (RendererStack::Renderer::OpenGL); + break; + case 2: + newVidApi = (RendererStack::Renderer::OpenGLES); + break; + case 3: + newVidApi = (RendererStack::Renderer::OpenGL3); + break; + case 4: + newVidApi = (RendererStack::Renderer::Vulkan); + break; + case 5: + newVidApi = (RendererStack::Renderer::Direct3D9); + break; +#ifdef USE_VNC + case 6: + { + newVidApi = RendererStack::Renderer::Software; + startblit(); + vnc_enabled = vnc_init(nullptr); + endblit(); + } #endif } ui->stackedWidget->switchRenderer(newVidApi); - if (!show_second_monitors) return; + if (!show_second_monitors) + return; for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i]) renderers[i]->switchRenderer(newVidApi); + if (renderers[i]) + renderers[i]->switchRenderer(newVidApi); } }); @@ -426,36 +431,36 @@ MainWindow::MainWindow(QWidget *parent) : } switch (scale) { - case 0: - ui->action0_5x->setChecked(true); - break; - case 1: - ui->action1x->setChecked(true); - break; - case 2: - ui->action1_5x->setChecked(true); - break; - case 3: - ui->action2x->setChecked(true); - break; - case 4: - ui->action3x->setChecked(true); - break; - case 5: - ui->action4x->setChecked(true); - break; - case 6: - ui->action5x->setChecked(true); - break; - case 7: - ui->action6x->setChecked(true); - break; - case 8: - ui->action7x->setChecked(true); - break; - case 9: - ui->action8x->setChecked(true); - break; + case 0: + ui->action0_5x->setChecked(true); + break; + case 1: + ui->action1x->setChecked(true); + break; + case 2: + ui->action1_5x->setChecked(true); + break; + case 3: + ui->action2x->setChecked(true); + break; + case 4: + ui->action3x->setChecked(true); + break; + case 5: + ui->action4x->setChecked(true); + break; + case 6: + ui->action5x->setChecked(true); + break; + case 7: + ui->action6x->setChecked(true); + break; + case 8: + ui->action7x->setChecked(true); + break; + case 9: + ui->action8x->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->action0_5x); @@ -469,29 +474,29 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->action7x); actGroup->addAction(ui->action8x); switch (video_filter_method) { - case 0: - ui->actionNearest->setChecked(true); - break; - case 1: - ui->actionLinear->setChecked(true); - break; + case 0: + ui->actionNearest->setChecked(true); + break; + case 1: + ui->actionLinear->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionNearest); actGroup->addAction(ui->actionLinear); switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: - ui->actionFullScreen_stretch->setChecked(true); - break; - case FULLSCR_SCALE_43: - ui->actionFullScreen_43->setChecked(true); - break; - case FULLSCR_SCALE_KEEPRATIO: - ui->actionFullScreen_keepRatio->setChecked(true); - break; - case FULLSCR_SCALE_INT: - ui->actionFullScreen_int->setChecked(true); - break; + case FULLSCR_SCALE_FULL: + ui->actionFullScreen_stretch->setChecked(true); + break; + case FULLSCR_SCALE_43: + ui->actionFullScreen_43->setChecked(true); + break; + case FULLSCR_SCALE_KEEPRATIO: + ui->actionFullScreen_keepRatio->setChecked(true); + break; + case FULLSCR_SCALE_INT: + ui->actionFullScreen_int->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionFullScreen_stretch); @@ -499,21 +504,21 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionFullScreen_keepRatio); actGroup->addAction(ui->actionFullScreen_int); switch (video_grayscale) { - case 0: - ui->actionRGB_Color->setChecked(true); - break; - case 1: - ui->actionRGB_Grayscale->setChecked(true); - break; - case 2: - ui->actionAmber_monitor->setChecked(true); - break; - case 3: - ui->actionGreen_monitor->setChecked(true); - break; - case 4: - ui->actionWhite_monitor->setChecked(true); - break; + case 0: + ui->actionRGB_Color->setChecked(true); + break; + case 1: + ui->actionRGB_Grayscale->setChecked(true); + break; + case 2: + ui->actionAmber_monitor->setChecked(true); + break; + case 3: + ui->actionGreen_monitor->setChecked(true); + break; + case 4: + ui->actionWhite_monitor->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionRGB_Grayscale); @@ -522,15 +527,15 @@ MainWindow::MainWindow(QWidget *parent) : actGroup->addAction(ui->actionWhite_monitor); actGroup->addAction(ui->actionRGB_Color); switch (video_graytype) { - case 0: - ui->actionBT601_NTSC_PAL->setChecked(true); - break; - case 1: - ui->actionBT709_HDTV->setChecked(true); - break; - case 2: - ui->actionAverage->setChecked(true); - break; + case 0: + ui->actionBT601_NTSC_PAL->setChecked(true); + break; + case 1: + ui->actionBT709_HDTV->setChecked(true); + break; + case 2: + ui->actionAverage->setChecked(true); + break; } actGroup = new QActionGroup(this); actGroup->addAction(ui->actionBT601_NTSC_PAL); @@ -551,7 +556,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionCtrl_Alt_Del->setShortcutVisibleInContextMenu(true); ui->actionTake_screenshot->setShortcutVisibleInContextMenu(true); #endif - if (!vnc_enabled) video_setblit(qt_blit); + if (!vnc_enabled) + video_setblit(qt_blit); #ifdef MTR_ENABLED { @@ -560,32 +566,30 @@ MainWindow::MainWindow(QWidget *parent) : ui->actionBegin_trace->setShortcut(QKeySequence(Qt::Key_Control + Qt::Key_T)); ui->actionEnd_trace->setShortcut(QKeySequence(Qt::Key_Control + Qt::Key_T)); ui->actionEnd_trace->setDisabled(true); - static auto init_trace = [&] - { + static auto init_trace = [&] { mtr_init("trace.json"); mtr_start(); }; - static auto shutdown_trace = [&] - { + static auto shutdown_trace = [&] { mtr_stop(); mtr_shutdown(); }; -#ifdef Q_OS_MACOS +# ifdef Q_OS_MACOS ui->actionBegin_trace->setShortcutVisibleInContextMenu(true); ui->actionEnd_trace->setShortcutVisibleInContextMenu(true); -#endif +# endif static bool trace = false; - connect(ui->actionBegin_trace, &QAction::triggered, this, [this] - { - if (trace) return; + connect(ui->actionBegin_trace, &QAction::triggered, this, [this] { + if (trace) + return; ui->actionBegin_trace->setDisabled(true); ui->actionEnd_trace->setDisabled(false); init_trace(); trace = true; }); - connect(ui->actionEnd_trace, &QAction::triggered, this, [this] - { - if (!trace) return; + connect(ui->actionEnd_trace, &QAction::triggered, this, [this] { + if (!trace) + return; ui->actionBegin_trace->setDisabled(false); ui->actionEnd_trace->setDisabled(true); shutdown_trace(); @@ -602,33 +606,34 @@ MainWindow::MainWindow(QWidget *parent) : connect(this, &MainWindow::destroyRendererMonitorForNonQtThread, this, &MainWindow::destroyRendererMonitorSlot, Qt::BlockingQueuedConnection); #ifdef Q_OS_MACOS - QTimer::singleShot(0, this, [this] () { - for (auto curObj : this->menuBar()->children()) { - if (qobject_cast(curObj)) { - auto menu = qobject_cast(curObj); - menu->setSeparatorsCollapsible(false); - for (auto curObj2 : menu->children()) { - if (qobject_cast(curObj2)) { - auto menu2 = qobject_cast(curObj2); - menu2->setSeparatorsCollapsible(false); - } - } - } - } - }); + QTimer::singleShot(0, this, [this]() { + for (auto curObj : this->menuBar()->children()) { + if (qobject_cast(curObj)) { + auto menu = qobject_cast(curObj); + menu->setSeparatorsCollapsible(false); + for (auto curObj2 : menu->children()) { + if (qobject_cast(curObj2)) { + auto menu2 = qobject_cast(curObj2); + menu2->setSeparatorsCollapsible(false); + } + } + } + } + }); #endif } -void MainWindow::closeEvent(QCloseEvent *event) { +void +MainWindow::closeEvent(QCloseEvent *event) +{ if (mouse_capture) { event->ignore(); return; } - if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) - { + if (confirm_exit && confirm_exit_cmdl && cpu_thread_run) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to exit 86Box?"), QMessageBox::Yes | QMessageBox::No, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); @@ -653,7 +658,8 @@ void MainWindow::closeEvent(QCloseEvent *event) { if (renderers[i]) { monitor_settings[i].mon_window_w = renderers[i]->geometry().width(); monitor_settings[i].mon_window_h = renderers[i]->geometry().height(); - if (QApplication::platformName().contains("wayland")) continue; + if (QApplication::platformName().contains("wayland")) + continue; monitor_settings[i].mon_window_x = renderers[i]->geometry().x(); monitor_settings[i].mon_window_y = renderers[i]->geometry().y(); } @@ -672,13 +678,13 @@ void MainWindow::closeEvent(QCloseEvent *event) { event->accept(); } -void MainWindow::initRendererMonitorSlot(int monitor_index) +void +MainWindow::initRendererMonitorSlot(int monitor_index) { - auto& secondaryRenderer = this->renderers[monitor_index]; + auto &secondaryRenderer = this->renderers[monitor_index]; secondaryRenderer.reset(new RendererStack(nullptr, monitor_index)); if (secondaryRenderer) { - connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] - { + connect(secondaryRenderer.get(), &RendererStack::rendererChanged, this, [this, monitor_index] { this->renderers[monitor_index]->show(); }); secondaryRenderer->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint); @@ -692,20 +698,20 @@ void MainWindow::initRendererMonitorSlot(int monitor_index) secondaryRenderer->show(); if (window_remember) { secondaryRenderer->setGeometry(monitor_settings[monitor_index].mon_window_x < 120 ? 120 : monitor_settings[monitor_index].mon_window_x, - monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, - monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, - monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); + monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, + monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, + monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } if (monitor_settings[monitor_index].mon_window_maximized) { secondaryRenderer->showMaximized(); } - secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api); + secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); } - } } -void MainWindow::destroyRendererMonitorSlot(int monitor_index) +void +MainWindow::destroyRendererMonitorSlot(int monitor_index) { if (this->renderers[monitor_index]) { if (window_remember) { @@ -719,26 +725,29 @@ void MainWindow::destroyRendererMonitorSlot(int monitor_index) } } -MainWindow::~MainWindow() { +MainWindow::~MainWindow() +{ delete ui; } -void MainWindow::showEvent(QShowEvent *event) { - if (shownonce) return; +void +MainWindow::showEvent(QShowEvent *event) +{ + if (shownonce) + return; shownonce = true; if (window_remember) { - if (window_w == 0) window_w = 320; - if (window_h == 0) window_h = 200; + if (window_w == 0) + window_w = 320; + if (window_h == 0) + window_h = 200; } if (window_remember && !QApplication::platformName().contains("wayland")) { setGeometry(window_x, window_y, window_w, window_h + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } if (vid_resize == 2) { - setFixedSize(fixed_size_x, fixed_size_y - + menuBar()->height() - + (hide_status_bar ? 0 : statusBar()->height()) - + (hide_tool_bar ? 0 : ui->toolBar->height())); + setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); monitors[0].mon_scrnsz_x = fixed_size_x; monitors[0].mon_scrnsz_y = fixed_size_y; @@ -754,17 +763,22 @@ void MainWindow::showEvent(QShowEvent *event) { } } -void MainWindow::on_actionKeyboard_requires_capture_triggered() { +void +MainWindow::on_actionKeyboard_requires_capture_triggered() +{ kbd_req_capture ^= 1; } -void MainWindow::on_actionRight_CTRL_is_left_ALT_triggered() { +void +MainWindow::on_actionRight_CTRL_is_left_ALT_triggered() +{ rctrl_is_lalt ^= 1; } -void MainWindow::on_actionHard_Reset_triggered() { - if (confirm_reset) - { +void +MainWindow::on_actionHard_Reset_triggered() +{ + if (confirm_reset) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to hard reset the emulated machine?"), QMessageBox::NoButton, this); questionbox.addButton(tr("Reset"), QMessageBox::AcceptRole); questionbox.addButton(tr("Don't reset"), QMessageBox::RejectRole); @@ -776,8 +790,7 @@ void MainWindow::on_actionHard_Reset_triggered() { confirm_reset = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); - if (questionbox.result() == QDialog::Accepted) - { + if (questionbox.result() == QDialog::Accepted) { confirm_reset = true; return; } @@ -786,23 +799,33 @@ void MainWindow::on_actionHard_Reset_triggered() { pc_reset_hard(); } -void MainWindow::on_actionCtrl_Alt_Del_triggered() { +void +MainWindow::on_actionCtrl_Alt_Del_triggered() +{ pc_send_cad(); } -void MainWindow::on_actionCtrl_Alt_Esc_triggered() { +void +MainWindow::on_actionCtrl_Alt_Esc_triggered() +{ pc_send_cae(); } -void MainWindow::on_actionPause_triggered() { +void +MainWindow::on_actionPause_triggered() +{ plat_pause(dopause ^ 1); } -void MainWindow::on_actionExit_triggered() { +void +MainWindow::on_actionExit_triggered() +{ close(); } -void MainWindow::on_actionSettings_triggered() { +void +MainWindow::on_actionSettings_triggered() +{ int currentPause = dopause; plat_pause(1); Settings settings(this); @@ -811,27 +834,26 @@ void MainWindow::on_actionSettings_triggered() { settings.exec(); switch (settings.result()) { - case QDialog::Accepted: - /* - pc_reset_hard_close(); - settings.save(); - config_changed = 2; - pc_reset_hard_init(); - */ - settings.save(); - config_changed = 2; - pc_reset_hard(); + case QDialog::Accepted: + /* + pc_reset_hard_close(); + settings.save(); + config_changed = 2; + pc_reset_hard_init(); + */ + settings.save(); + config_changed = 2; + pc_reset_hard(); - break; - case QDialog::Rejected: - break; + break; + case QDialog::Rejected: + break; } plat_pause(currentPause); } #if defined(__unix__) && !defined(__HAIKU__) -std::array x11_to_xt_base -{ +std::array x11_to_xt_base { 0, 0, 0, @@ -953,8 +975,7 @@ std::array x11_to_xt_base 0x15D, }; -std::array x11_to_xt_2 -{ +std::array x11_to_xt_2 { 0, 0, 0, @@ -1093,8 +1114,7 @@ std::array x11_to_xt_2 0x15D }; -std::array x11_to_xt_vnc -{ +std::array x11_to_xt_vnc { 0, 0, 0, @@ -1176,8 +1196,7 @@ std::array x11_to_xt_vnc #endif #ifdef Q_OS_MACOS -std::array darwin_to_xt -{ +std::array darwin_to_xt { 0x1E, 0x1F, 0x20, @@ -1310,143 +1329,142 @@ std::array darwin_to_xt #endif #if defined(__unix__) && !defined(__HAIKU__) -static std::unordered_map evdev_to_xt = - { - {96, 0x11C}, - {97, 0x11D}, - {98, 0x135}, - {99, 0x71}, - {100, 0x138}, - {101, 0x1C}, - {102, 0x147}, - {103, 0x148}, - {104, 0x149}, - {105, 0x14B}, - {106, 0x14D}, - {107, 0x14F}, - {108, 0x150}, - {109, 0x151}, - {110, 0x152}, - {111, 0x153} +static std::unordered_map evdev_to_xt = { + {96, 0x11C}, + { 97, 0x11D}, + { 98, 0x135}, + { 99, 0x71 }, + { 100, 0x138}, + { 101, 0x1C }, + { 102, 0x147}, + { 103, 0x148}, + { 104, 0x149}, + { 105, 0x14B}, + { 106, 0x14D}, + { 107, 0x14F}, + { 108, 0x150}, + { 109, 0x151}, + { 110, 0x152}, + { 111, 0x153} }; #endif #ifdef __HAIKU__ -static std::unordered_map be_to_xt = -{ - {0x01, 0x01}, - {B_F1_KEY, 0x3B}, - {B_F2_KEY, 0x3C}, - {B_F3_KEY, 0x3D}, - {B_F4_KEY, 0x3E}, - {B_F5_KEY, 0x3F}, - {B_F6_KEY, 0x40}, - {B_F7_KEY, 0x41}, - {B_F8_KEY, 0x42}, - {B_F9_KEY, 0x43}, - {B_F10_KEY, 0x44}, - {B_F11_KEY, 0x57}, - {B_F12_KEY, 0x58}, - {0x11, 0x29}, - {0x12, 0x02}, - {0x13, 0x03}, - {0x14, 0x04}, - {0x15, 0x05}, - {0x16, 0x06}, - {0x17, 0x07}, - {0x18, 0x08}, - {0x19, 0x09}, - {0x1A, 0x0A}, - {0x1B, 0x0B}, - {0x1C, 0x0C}, - {0x1D, 0x0D}, - {0x1E, 0x0E}, - {0x1F, 0x152}, - {0x20, 0x147}, - {0x21, 0x149}, - {0x22, 0x45}, - {0x23, 0x135}, - {0x24, 0x37}, - {0x25, 0x4A}, - {0x26, 0x0F}, - {0x27, 0x10}, - {0x28, 0x11}, - {0x29, 0x12}, - {0x2A, 0x13}, - {0x2B, 0x14}, - {0x2C, 0x15}, - {0x2D, 0x16}, - {0x2E, 0x17}, - {0x2F, 0x18}, - {0x30, 0x19}, - {0x31, 0x1A}, - {0x32, 0x1B}, - {0x33, 0x2B}, - {0x34, 0x153}, - {0x35, 0x14F}, - {0x36, 0x151}, - {0x37, 0x47}, - {0x38, 0x48}, - {0x39, 0x49}, - {0x3A, 0x4E}, - {0x3B, 0x3A}, - {0x3C, 0x1E}, - {0x3D, 0x1F}, - {0x3E, 0x20}, - {0x3F, 0x21}, - {0x40, 0x22}, - {0x41, 0x23}, - {0x42, 0x24}, - {0x43, 0x25}, - {0x44, 0x26}, - {0x45, 0x27}, - {0x46, 0x28}, - {0x47, 0x1C}, - {0x48, 0x4B}, - {0x49, 0x4C}, - {0x4A, 0x4D}, - {0x4B, 0x2A}, - {0x4C, 0x2C}, - {0x4D, 0x2D}, - {0x4E, 0x2E}, - {0x4F, 0x2F}, - {0x50, 0x30}, - {0x51, 0x31}, - {0x52, 0x32}, - {0x53, 0x33}, - {0x54, 0x34}, - {0x55, 0x35}, - {0x56, 0x36}, - {0x57, 0x148}, - {0x58, 0x51}, - {0x59, 0x50}, - {0x5A, 0x4F}, - {0x5B, 0x11C}, - {0x5C, 0x1D}, - {0x5D, 0x38}, - {0x5E, 0x39}, - {0x5F, 0x138}, - {0x60, 0x11D}, - {0x61, 0x14B}, - {0x62, 0x150}, - {0x63, 0x14D}, - {0x64, 0x52}, - {0x65, 0x53}, +static std::unordered_map be_to_xt = { + {0x01, 0x01 }, + { B_F1_KEY, 0x3B }, + { B_F2_KEY, 0x3C }, + { B_F3_KEY, 0x3D }, + { B_F4_KEY, 0x3E }, + { B_F5_KEY, 0x3F }, + { B_F6_KEY, 0x40 }, + { B_F7_KEY, 0x41 }, + { B_F8_KEY, 0x42 }, + { B_F9_KEY, 0x43 }, + { B_F10_KEY, 0x44 }, + { B_F11_KEY, 0x57 }, + { B_F12_KEY, 0x58 }, + { 0x11, 0x29 }, + { 0x12, 0x02 }, + { 0x13, 0x03 }, + { 0x14, 0x04 }, + { 0x15, 0x05 }, + { 0x16, 0x06 }, + { 0x17, 0x07 }, + { 0x18, 0x08 }, + { 0x19, 0x09 }, + { 0x1A, 0x0A }, + { 0x1B, 0x0B }, + { 0x1C, 0x0C }, + { 0x1D, 0x0D }, + { 0x1E, 0x0E }, + { 0x1F, 0x152}, + { 0x20, 0x147}, + { 0x21, 0x149}, + { 0x22, 0x45 }, + { 0x23, 0x135}, + { 0x24, 0x37 }, + { 0x25, 0x4A }, + { 0x26, 0x0F }, + { 0x27, 0x10 }, + { 0x28, 0x11 }, + { 0x29, 0x12 }, + { 0x2A, 0x13 }, + { 0x2B, 0x14 }, + { 0x2C, 0x15 }, + { 0x2D, 0x16 }, + { 0x2E, 0x17 }, + { 0x2F, 0x18 }, + { 0x30, 0x19 }, + { 0x31, 0x1A }, + { 0x32, 0x1B }, + { 0x33, 0x2B }, + { 0x34, 0x153}, + { 0x35, 0x14F}, + { 0x36, 0x151}, + { 0x37, 0x47 }, + { 0x38, 0x48 }, + { 0x39, 0x49 }, + { 0x3A, 0x4E }, + { 0x3B, 0x3A }, + { 0x3C, 0x1E }, + { 0x3D, 0x1F }, + { 0x3E, 0x20 }, + { 0x3F, 0x21 }, + { 0x40, 0x22 }, + { 0x41, 0x23 }, + { 0x42, 0x24 }, + { 0x43, 0x25 }, + { 0x44, 0x26 }, + { 0x45, 0x27 }, + { 0x46, 0x28 }, + { 0x47, 0x1C }, + { 0x48, 0x4B }, + { 0x49, 0x4C }, + { 0x4A, 0x4D }, + { 0x4B, 0x2A }, + { 0x4C, 0x2C }, + { 0x4D, 0x2D }, + { 0x4E, 0x2E }, + { 0x4F, 0x2F }, + { 0x50, 0x30 }, + { 0x51, 0x31 }, + { 0x52, 0x32 }, + { 0x53, 0x33 }, + { 0x54, 0x34 }, + { 0x55, 0x35 }, + { 0x56, 0x36 }, + { 0x57, 0x148}, + { 0x58, 0x51 }, + { 0x59, 0x50 }, + { 0x5A, 0x4F }, + { 0x5B, 0x11C}, + { 0x5C, 0x1D }, + { 0x5D, 0x38 }, + { 0x5E, 0x39 }, + { 0x5F, 0x138}, + { 0x60, 0x11D}, + { 0x61, 0x14B}, + { 0x62, 0x150}, + { 0x63, 0x14D}, + { 0x64, 0x52 }, + { 0x65, 0x53 }, - {0x0e, 0x137}, - {0x0f, 0x46}, - {0x66, 0x15B}, - {0x67, 0x15C}, - {0x68, 0x15D}, - {0x69, 0x56} + { 0x0e, 0x137}, + { 0x0f, 0x46 }, + { 0x66, 0x15B}, + { 0x67, 0x15C}, + { 0x68, 0x15D}, + { 0x69, 0x56 } }; #endif #if defined(__unix__) && !defined(__HAIKU__) -static std::array& selected_keycode = x11_to_xt_base; +static std::array &selected_keycode = x11_to_xt_base; #endif -uint16_t x11_keycode_to_keysym(uint32_t keycode) +uint16_t +x11_keycode_to_keysym(uint32_t keycode) { uint16_t finalkeycode = 0; #if defined(Q_OS_WINDOWS) @@ -1456,33 +1474,27 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode) #elif defined(__HAIKU__) finalkeycode = be_to_xt[keycode]; #else - static Display* x11display = nullptr; - if (QApplication::platformName().contains("wayland")) - { + static Display *x11display = nullptr; + if (QApplication::platformName().contains("wayland")) { selected_keycode = x11_to_xt_2; - } - else if (QApplication::platformName().contains("eglfs")) - { + } else if (QApplication::platformName().contains("eglfs")) { keycode -= 8; - if (keycode <= 88) finalkeycode = keycode; - else finalkeycode = evdev_to_xt[keycode]; - } - else if (!x11display) - { + if (keycode <= 88) + finalkeycode = keycode; + else + finalkeycode = evdev_to_xt[keycode]; + } else if (!x11display) { x11display = XOpenDisplay(nullptr); - if (XKeysymToKeycode(x11display, XK_Home) == 110) - { + if (XKeysymToKeycode(x11display, XK_Home) == 110) { selected_keycode = x11_to_xt_2; - } - else if (XKeysymToKeycode(x11display, XK_Home) == 69) - { + } else if (XKeysymToKeycode(x11display, XK_Home) == 69) { selected_keycode = x11_to_xt_vnc; } } - if (!QApplication::platformName().contains("eglfs")) finalkeycode = selected_keycode[keycode]; + if (!QApplication::platformName().contains("eglfs")) + finalkeycode = selected_keycode[keycode]; #endif - if (rctrl_is_lalt && finalkeycode == 0x11D) - { + if (rctrl_is_lalt && finalkeycode == 0x11D) { finalkeycode = 0x38; } return finalkeycode; @@ -1493,18 +1505,20 @@ uint16_t x11_keycode_to_keysym(uint32_t keycode) // that's followed up with "(really?)". It's the only way to distinguish // left and right modifiers with Qt 6 on macOS, so let's just roll with it. static std::unordered_map mac_modifiers_to_xt = { - {NX_DEVICELCTLKEYMASK, 0x1D}, - {NX_DEVICELSHIFTKEYMASK, 0x2A}, - {NX_DEVICERSHIFTKEYMASK, 0x36}, - {NX_DEVICELCMDKEYMASK, 0x15B}, - {NX_DEVICERCMDKEYMASK, 0x15C}, - {NX_DEVICELALTKEYMASK, 0x38}, - {NX_DEVICERALTKEYMASK, 0x138}, - {NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A}, - {NX_DEVICERCTLKEYMASK, 0x11D}, + {NX_DEVICELCTLKEYMASK, 0x1D }, + { NX_DEVICELSHIFTKEYMASK, 0x2A }, + { NX_DEVICERSHIFTKEYMASK, 0x36 }, + { NX_DEVICELCMDKEYMASK, 0x15B}, + { NX_DEVICERCMDKEYMASK, 0x15C}, + { NX_DEVICELALTKEYMASK, 0x38 }, + { NX_DEVICERALTKEYMASK, 0x138}, + { NX_DEVICE_ALPHASHIFT_STATELESS_MASK, 0x3A }, + { NX_DEVICERCTLKEYMASK, 0x11D}, }; -void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) { +void +MainWindow::processMacKeyboardInput(bool down, const QKeyEvent *event) +{ // Per QTBUG-69608 (https://bugreports.qt.io/browse/QTBUG-69608), // QKeyEvents QKeyEvents for presses/releases of modifiers on macOS give // nativeVirtualKey() == 0 (at least in Qt 6). Handle this by manually @@ -1521,7 +1535,7 @@ void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) { // We only process one modifier at a time since events from Qt seem to // always be non-coalesced (NX_NONCOALESCEDMASK is always set). uint32_t changed_modifiers = last_modifiers ^ event->nativeModifiers(); - for (auto const& pair : mac_modifiers_to_xt) { + for (auto const &pair : mac_modifiers_to_xt) { if (changed_modifiers & pair.first) { last_modifiers ^= pair.first; keyboard_input(down, pair.second); @@ -1550,24 +1564,28 @@ void MainWindow::processMacKeyboardInput(bool down, const QKeyEvent* event) { } #endif -void MainWindow::on_actionFullscreen_triggered() { +void +MainWindow::on_actionFullscreen_triggered() +{ if (video_fullscreen > 0) { showNormal(); - if (vid_api == 5) QTimer::singleShot(0, this, [this] () { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); + if (vid_api == 5) + QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); ui->menubar->show(); - if (!hide_status_bar) ui->statusbar->show(); - if (!hide_tool_bar) ui->toolBar->show(); + if (!hide_status_bar) + ui->statusbar->show(); + if (!hide_tool_bar) + ui->toolBar->show(); video_fullscreen = 0; if (vid_resize != 1) { emit resizeContents(vid_resize == 2 ? fixed_size_x : monitors[0].mon_scrnsz_x, vid_resize == 2 ? fixed_size_y : monitors[0].mon_scrnsz_y); } } else { - if (video_fullscreen_first) - { + if (video_fullscreen_first) { bool wasCaptured = mouse_capture == 1; QMessageBox questionbox(QMessageBox::Icon::Information, tr("Entering fullscreen mode"), tr("Press Ctrl+Alt+PgDn to return to windowed mode."), QMessageBox::Ok, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!video_fullscreen_first); @@ -1588,17 +1606,20 @@ void MainWindow::on_actionFullscreen_triggered() { ui->toolBar->hide(); ui->stackedWidget->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); showFullScreen(); - if (vid_api == 5) QTimer::singleShot(0, this, [this] () { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); + if (vid_api == 5) + QTimer::singleShot(0, this, [this]() { ui->stackedWidget->switchRenderer(RendererStack::Renderer::Direct3D9); }); } ui->stackedWidget->onResize(width(), height()); } -void MainWindow::getTitle_(wchar_t *title) +void +MainWindow::getTitle_(wchar_t *title) { this->windowTitle().toWCharArray(title); } -void MainWindow::getTitle(wchar_t *title) +void +MainWindow::getTitle(wchar_t *title) { if (QThread::currentThread() == this->thread()) { getTitle_(title); @@ -1607,11 +1628,12 @@ void MainWindow::getTitle(wchar_t *title) } } -bool MainWindow::eventFilter(QObject* receiver, QEvent* event) +bool +MainWindow::eventFilter(QObject *receiver, QEvent *event) { if (!dopause && (mouse_capture || !kbd_req_capture)) { if (event->type() == QEvent::Shortcut) { - auto shortcutEvent = (QShortcutEvent*)event; + auto shortcutEvent = (QShortcutEvent *) event; if (shortcutEvent->key() == ui->actionExit->shortcut()) { event->accept(); return true; @@ -1643,13 +1665,17 @@ bool MainWindow::eventFilter(QObject* receiver, QEvent* event) return QMainWindow::eventFilter(receiver, event); } -void MainWindow::refreshMediaMenu() { +void +MainWindow::refreshMediaMenu() +{ mm->refresh(ui->menuMedia); status->refresh(ui->statusbar); ui->actionMCA_devices->setVisible(machine_has_bus(machine, MACHINE_BUS_MCA)); } -void MainWindow::showMessage(int flags, const QString& header, const QString& message) { +void +MainWindow::showMessage(int flags, const QString &header, const QString &message) +{ if (QThread::currentThread() == this->thread()) { showMessage_(flags, header, message); } else { @@ -1657,23 +1683,25 @@ void MainWindow::showMessage(int flags, const QString& header, const QString& me } } -void MainWindow::showMessage_(int flags, const QString &header, const QString &message) { +void +MainWindow::showMessage_(int flags, const QString &header, const QString &message) +{ QMessageBox box(QMessageBox::Warning, header, message, QMessageBox::NoButton, this); if (flags & (MBX_FATAL)) { box.setIcon(QMessageBox::Critical); - } - else if (!(flags & (MBX_ERROR | MBX_WARNING))) { + } else if (!(flags & (MBX_ERROR | MBX_WARNING))) { box.setIcon(QMessageBox::Warning); } box.setTextFormat(Qt::TextFormat::RichText); box.exec(); - if (cpu_thread_run == 0) QApplication::exit(-1); + if (cpu_thread_run == 0) + QApplication::exit(-1); } -void MainWindow::keyPressEvent(QKeyEvent* event) +void +MainWindow::keyPressEvent(QKeyEvent *event) { - if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) - { + if (send_keyboard_input && !(kbd_req_capture && !mouse_capture)) { // Windows keys in Qt have one-to-one mapping. if (event->key() == Qt::Key_Pause && !keyboard_recv(0x38) && !keyboard_recv(0x138)) { if ((keyboard_recv(0x1D) || keyboard_recv(0x11D))) { @@ -1688,9 +1716,9 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } } else #ifdef Q_OS_MACOS - processMacKeyboardInput(true, event); + processMacKeyboardInput(true, event); #else - keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode())); + keyboard_input(1, x11_keycode_to_keysym(event->nativeScanCode())); #endif } @@ -1703,23 +1731,29 @@ void MainWindow::keyPressEvent(QKeyEvent* event) } if ((video_fullscreen > 0) && (keyboard_recv(0x1D) || keyboard_recv(0x11D))) { - if (keyboard_recv(0x57)) ui->actionTake_screenshot->trigger(); - else if (keyboard_recv(0x58)) pc_send_cad(); + if (keyboard_recv(0x57)) + ui->actionTake_screenshot->trigger(); + else if (keyboard_recv(0x58)) + pc_send_cad(); } event->accept(); } -void MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) +void +MainWindow::blitToWidget(int x, int y, int w, int h, int monitor_index) { if (monitor_index >= 1) { - if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) renderers[monitor_index]->blit(x, y, w, h); - else video_blit_complete_monitor(monitor_index); - } - else ui->stackedWidget->blit(x, y, w, h); + if (!blitDummied && renderers[monitor_index] && renderers[monitor_index]->isVisible()) + renderers[monitor_index]->blit(x, y, w, h); + else + video_blit_complete_monitor(monitor_index); + } else + ui->stackedWidget->blit(x, y, w, h); } -void MainWindow::keyReleaseEvent(QKeyEvent* event) +void +MainWindow::keyReleaseEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Pause) { if (keyboard_recv(0x38) && keyboard_recv(0x138)) { @@ -1736,22 +1770,27 @@ void MainWindow::keyReleaseEvent(QKeyEvent* event) #endif } -QSize MainWindow::getRenderWidgetSize() +QSize +MainWindow::getRenderWidgetSize() { return ui->stackedWidget->size(); } -void MainWindow::focusInEvent(QFocusEvent* event) +void +MainWindow::focusInEvent(QFocusEvent *event) { this->grabKeyboard(); } -void MainWindow::focusOutEvent(QFocusEvent* event) +void +MainWindow::focusOutEvent(QFocusEvent *event) { this->releaseKeyboard(); } -void MainWindow::on_actionResizable_window_triggered(bool checked) { +void +MainWindow::on_actionResizable_window_triggered(bool checked) +{ if (checked) { vid_resize = 1; setWindowFlag(Qt::WindowMaximizeButtonHint); @@ -1775,20 +1814,20 @@ void MainWindow::on_actionResizable_window_triggered(bool checked) { } } show(); - ui->menuWindow_scale_factor->setEnabled(! checked); + ui->menuWindow_scale_factor->setEnabled(!checked); emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); - ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api); + ui->stackedWidget->switchRenderer((RendererStack::Renderer) vid_api); for (int i = 1; i < MONITORS_NUM; i++) { if (monitors[i].target_buffer && show_second_monitors) { renderers[i]->show(); - renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); + renderers[i]->switchRenderer((RendererStack::Renderer) vid_api); QApplication::processEvents(); } } } static void -video_toggle_option(QAction* action, int *val) +video_toggle_option(QAction *action, int *val) { startblit(); *val ^= 1; @@ -1798,15 +1837,20 @@ video_toggle_option(QAction* action, int *val) config_save(); device_force_redraw(); for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].target_buffer) video_force_resize_set_monitor(1, i); + if (monitors[i].target_buffer) + video_force_resize_set_monitor(1, i); } } -void MainWindow::on_actionInverted_VGA_monitor_triggered() { +void +MainWindow::on_actionInverted_VGA_monitor_triggered() +{ video_toggle_option(ui->actionInverted_VGA_monitor, &invert_display); } -static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { +static void +update_scaled_checkboxes(Ui::MainWindow *ui, QAction *selected) +{ ui->action0_5x->setChecked(ui->action0_5x == selected); ui->action1x->setChecked(ui->action1x == selected); ui->action1_5x->setChecked(ui->action1_5x == selected); @@ -1821,72 +1865,99 @@ static void update_scaled_checkboxes(Ui::MainWindow* ui, QAction* selected) { reset_screen_size(); device_force_redraw(); for (int i = 0; i < MONITORS_NUM; i++) { - if (monitors[i].target_buffer) video_force_resize_set_monitor(1, i); + if (monitors[i].target_buffer) + video_force_resize_set_monitor(1, i); } config_save(); } -void MainWindow::on_action0_5x_triggered() { +void +MainWindow::on_action0_5x_triggered() +{ scale = 0; update_scaled_checkboxes(ui, ui->action0_5x); } -void MainWindow::on_action1x_triggered() { +void +MainWindow::on_action1x_triggered() +{ scale = 1; update_scaled_checkboxes(ui, ui->action1x); } -void MainWindow::on_action1_5x_triggered() { +void +MainWindow::on_action1_5x_triggered() +{ scale = 2; update_scaled_checkboxes(ui, ui->action1_5x); } -void MainWindow::on_action2x_triggered() { +void +MainWindow::on_action2x_triggered() +{ scale = 3; update_scaled_checkboxes(ui, ui->action2x); } -void MainWindow::on_action3x_triggered() { +void +MainWindow::on_action3x_triggered() +{ scale = 4; update_scaled_checkboxes(ui, ui->action3x); } -void MainWindow::on_action4x_triggered() { +void +MainWindow::on_action4x_triggered() +{ scale = 5; update_scaled_checkboxes(ui, ui->action4x); } -void MainWindow::on_action5x_triggered() { +void +MainWindow::on_action5x_triggered() +{ scale = 6; update_scaled_checkboxes(ui, ui->action5x); } -void MainWindow::on_action6x_triggered() { +void +MainWindow::on_action6x_triggered() +{ scale = 7; update_scaled_checkboxes(ui, ui->action6x); } -void MainWindow::on_action7x_triggered() { +void +MainWindow::on_action7x_triggered() +{ scale = 8; update_scaled_checkboxes(ui, ui->action7x); } -void MainWindow::on_action8x_triggered() { +void +MainWindow::on_action8x_triggered() +{ scale = 9; update_scaled_checkboxes(ui, ui->action8x); } -void MainWindow::on_actionNearest_triggered() { +void +MainWindow::on_actionNearest_triggered() +{ video_filter_method = 0; ui->actionLinear->setChecked(false); } -void MainWindow::on_actionLinear_triggered() { +void +MainWindow::on_actionLinear_triggered() +{ video_filter_method = 1; ui->actionNearest->setChecked(false); } -static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* selected) { +static void +update_fullscreen_scale_checkboxes(Ui::MainWindow *ui, QAction *selected) +{ ui->actionFullScreen_stretch->setChecked(ui->actionFullScreen_stretch == selected); ui->actionFullScreen_43->setChecked(ui->actionFullScreen_43 == selected); ui->actionFullScreen_keepRatio->setChecked(ui->actionFullScreen_keepRatio == selected); @@ -1898,34 +1969,45 @@ static void update_fullscreen_scale_checkboxes(Ui::MainWindow* ui, QAction* sele } for (int i = 1; i < MONITORS_NUM; i++) { - if (main_window->renderers[i]) main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); + if (main_window->renderers[i]) + main_window->renderers[i]->onResize(main_window->renderers[i]->width(), main_window->renderers[i]->height()); } device_force_redraw(); config_save(); } -void MainWindow::on_actionFullScreen_stretch_triggered() { +void +MainWindow::on_actionFullScreen_stretch_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_FULL; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_stretch); } -void MainWindow::on_actionFullScreen_43_triggered() { +void +MainWindow::on_actionFullScreen_43_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_43; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_43); } -void MainWindow::on_actionFullScreen_keepRatio_triggered() { +void +MainWindow::on_actionFullScreen_keepRatio_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_KEEPRATIO; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_keepRatio); } -void MainWindow::on_actionFullScreen_int_triggered() { +void +MainWindow::on_actionFullScreen_int_triggered() +{ video_fullscreen_scale = FULLSCR_SCALE_INT; update_fullscreen_scale_checkboxes(ui, ui->actionFullScreen_int); } -static void update_greyscale_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { +static void +update_greyscale_checkboxes(Ui::MainWindow *ui, QAction *selected, int value) +{ ui->actionRGB_Color->setChecked(ui->actionRGB_Color == selected); ui->actionRGB_Grayscale->setChecked(ui->actionRGB_Grayscale == selected); ui->actionAmber_monitor->setChecked(ui->actionAmber_monitor == selected); @@ -1934,33 +2016,45 @@ static void update_greyscale_checkboxes(Ui::MainWindow* ui, QAction* selected, i startblit(); video_grayscale = value; - video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; + video_copy = (video_grayscale || invert_display) ? video_transform_copy : memcpy; endblit(); device_force_redraw(); config_save(); } -void MainWindow::on_actionRGB_Color_triggered() { +void +MainWindow::on_actionRGB_Color_triggered() +{ update_greyscale_checkboxes(ui, ui->actionRGB_Color, 0); } -void MainWindow::on_actionRGB_Grayscale_triggered() { +void +MainWindow::on_actionRGB_Grayscale_triggered() +{ update_greyscale_checkboxes(ui, ui->actionRGB_Grayscale, 1); } -void MainWindow::on_actionAmber_monitor_triggered() { +void +MainWindow::on_actionAmber_monitor_triggered() +{ update_greyscale_checkboxes(ui, ui->actionAmber_monitor, 2); } -void MainWindow::on_actionGreen_monitor_triggered() { +void +MainWindow::on_actionGreen_monitor_triggered() +{ update_greyscale_checkboxes(ui, ui->actionGreen_monitor, 3); } -void MainWindow::on_actionWhite_monitor_triggered() { +void +MainWindow::on_actionWhite_monitor_triggered() +{ update_greyscale_checkboxes(ui, ui->actionWhite_monitor, 4); } -static void update_greyscale_type_checkboxes(Ui::MainWindow* ui, QAction* selected, int value) { +static void +update_greyscale_type_checkboxes(Ui::MainWindow *ui, QAction *selected, int value) +{ ui->actionBT601_NTSC_PAL->setChecked(ui->actionBT601_NTSC_PAL == selected); ui->actionBT709_HDTV->setChecked(ui->actionBT709_HDTV == selected); ui->actionAverage->setChecked(ui->actionAverage == selected); @@ -1970,24 +2064,32 @@ static void update_greyscale_type_checkboxes(Ui::MainWindow* ui, QAction* select config_save(); } -void MainWindow::on_actionBT601_NTSC_PAL_triggered() { +void +MainWindow::on_actionBT601_NTSC_PAL_triggered() +{ update_greyscale_type_checkboxes(ui, ui->actionBT601_NTSC_PAL, 0); } -void MainWindow::on_actionBT709_HDTV_triggered() { +void +MainWindow::on_actionBT709_HDTV_triggered() +{ update_greyscale_type_checkboxes(ui, ui->actionBT709_HDTV, 1); } -void MainWindow::on_actionAverage_triggered() { +void +MainWindow::on_actionAverage_triggered() +{ update_greyscale_type_checkboxes(ui, ui->actionAverage, 2); } -void MainWindow::on_actionAbout_Qt_triggered() +void +MainWindow::on_actionAbout_Qt_triggered() { QApplication::aboutQt(); } -void MainWindow::on_actionAbout_86Box_triggered() +void +MainWindow::on_actionAbout_86Box_triggered() { QMessageBox msgBox; msgBox.setTextFormat(Qt::RichText); @@ -2000,8 +2102,7 @@ void MainWindow::on_actionAbout_86Box_triggered() msgBox.setWindowTitle("About 86Box"); msgBox.addButton("OK", QMessageBox::ButtonRole::AcceptRole); auto webSiteButton = msgBox.addButton(EMU_SITE, QMessageBox::ButtonRole::HelpRole); - webSiteButton->connect(webSiteButton, &QPushButton::released, []() - { + webSiteButton->connect(webSiteButton, &QPushButton::released, []() { QDesktopServices::openUrl(QUrl("https://" EMU_SITE)); }); #ifdef RELEASE_BUILD @@ -2017,27 +2118,35 @@ void MainWindow::on_actionAbout_86Box_triggered() msgBox.exec(); } -void MainWindow::on_actionDocumentation_triggered() +void +MainWindow::on_actionDocumentation_triggered() { - QDesktopServices::openUrl(QUrl(EMU_DOCS_URL)); + QDesktopServices::openUrl(QUrl(EMU_DOCS_URL)); } -void MainWindow::on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered() { +void +MainWindow::on_actionCGA_PCjr_Tandy_EGA_S_VGA_overscan_triggered() +{ update_overscan = 1; video_toggle_option(ui->actionCGA_PCjr_Tandy_EGA_S_VGA_overscan, &enable_overscan); } -void MainWindow::on_actionChange_contrast_for_monochrome_display_triggered() { +void +MainWindow::on_actionChange_contrast_for_monochrome_display_triggered() +{ vid_cga_contrast ^= 1; cgapal_rebuild(); config_save(); } -void MainWindow::on_actionForce_4_3_display_ratio_triggered() { +void +MainWindow::on_actionForce_4_3_display_ratio_triggered() +{ video_toggle_option(ui->actionForce_4_3_display_ratio, &force_43); } -void MainWindow::on_actionRemember_size_and_position_triggered() +void +MainWindow::on_actionRemember_size_and_position_triggered() { window_remember ^= 1; window_w = ui->stackedWidget->width(); @@ -2057,24 +2166,28 @@ void MainWindow::on_actionRemember_size_and_position_triggered() ui->actionRemember_size_and_position->setChecked(window_remember); } -void MainWindow::on_actionSpecify_dimensions_triggered() +void +MainWindow::on_actionSpecify_dimensions_triggered() { SpecifyDimensions dialog(this); dialog.setWindowModality(Qt::WindowModal); dialog.exec(); } -void MainWindow::on_actionHiDPI_scaling_triggered() +void +MainWindow::on_actionHiDPI_scaling_triggered() { dpi_scale ^= 1; ui->actionHiDPI_scaling->setChecked(dpi_scale); emit resizeContents(monitors[0].mon_scrnsz_x, monitors[0].mon_scrnsz_y); for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i]) emit resizeContentsMonitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i); + if (renderers[i]) + emit resizeContentsMonitor(monitors[i].mon_scrnsz_x, monitors[i].mon_scrnsz_y, i); } } -void MainWindow::on_actionHide_status_bar_triggered() +void +MainWindow::on_actionHide_status_bar_triggered() { auto w = ui->stackedWidget->width(); auto h = ui->stackedWidget->height(); @@ -2082,20 +2195,19 @@ void MainWindow::on_actionHide_status_bar_triggered() ui->actionHide_status_bar->setChecked(hide_status_bar); statusBar()->setVisible(!hide_status_bar); if (vid_resize >= 2) { - setFixedSize(fixed_size_x, fixed_size_y - + menuBar()->height() - + (hide_status_bar ? 0 : statusBar()->height()) - + (hide_tool_bar ? 0 : ui->toolBar->height())); + setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } else { int vid_resize_orig = vid_resize; - vid_resize = 0; + vid_resize = 0; emit resizeContents(w, h); vid_resize = vid_resize_orig; - if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (vid_resize == 1) + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } -void MainWindow::on_actionHide_tool_bar_triggered() +void +MainWindow::on_actionHide_tool_bar_triggered() { auto w = ui->stackedWidget->width(); auto h = ui->stackedWidget->height(); @@ -2103,26 +2215,26 @@ void MainWindow::on_actionHide_tool_bar_triggered() ui->actionHide_tool_bar->setChecked(hide_tool_bar); ui->toolBar->setVisible(!hide_tool_bar); if (vid_resize >= 2) { - setFixedSize(fixed_size_x, fixed_size_y - + menuBar()->height() - + (hide_status_bar ? 0 : statusBar()->height()) - + (hide_tool_bar ? 0 : ui->toolBar->height())); + setFixedSize(fixed_size_x, fixed_size_y + menuBar()->height() + (hide_status_bar ? 0 : statusBar()->height()) + (hide_tool_bar ? 0 : ui->toolBar->height())); } else { int vid_resize_orig = vid_resize; - vid_resize = 0; + vid_resize = 0; emit resizeContents(w, h); vid_resize = vid_resize_orig; - if (vid_resize == 1) setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); + if (vid_resize == 1) + setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); } } -void MainWindow::on_actionUpdate_status_bar_icons_triggered() +void +MainWindow::on_actionUpdate_status_bar_icons_triggered() { update_icons ^= 1; ui->actionUpdate_status_bar_icons->setChecked(update_icons); } -void MainWindow::on_actionTake_screenshot_triggered() +void +MainWindow::on_actionTake_screenshot_triggered() { startblit(); for (int i = 0; i < MONITORS_NUM; i++) @@ -2131,62 +2243,70 @@ void MainWindow::on_actionTake_screenshot_triggered() device_force_redraw(); } -void MainWindow::on_actionSound_gain_triggered() +void +MainWindow::on_actionSound_gain_triggered() { SoundGain gain(this); gain.exec(); } -void MainWindow::setSendKeyboardInput(bool enabled) +void +MainWindow::setSendKeyboardInput(bool enabled) { send_keyboard_input = enabled; } -void MainWindow::updateUiPauseState() { +void +MainWindow::updateUiPauseState() +{ auto pause_icon = dopause ? QIcon(":/menuicons/win/icons/run.ico") : QIcon(":/menuicons/win/icons/pause.ico"); auto tooltip_text = dopause ? QString(tr("Resume execution")) : QString(tr("Pause execution")); ui->actionPause->setIcon(pause_icon); ui->actionPause->setToolTip(tooltip_text); } -void MainWindow::on_actionPreferences_triggered() +void +MainWindow::on_actionPreferences_triggered() { ProgSettings progsettings(this); progsettings.exec(); } - -void MainWindow::on_actionEnable_Discord_integration_triggered(bool checked) +void +MainWindow::on_actionEnable_Discord_integration_triggered(bool checked) { enable_discord = checked; - if(enable_discord) { + if (enable_discord) { discord_init(); discord_update_activity(dopause); } else discord_close(); } -void MainWindow::showSettings() +void +MainWindow::showSettings() { - if (findChild() == nullptr) + if (findChild() == nullptr) ui->actionSettings->trigger(); } -void MainWindow::hardReset() +void +MainWindow::hardReset() { ui->actionHard_Reset->trigger(); } -void MainWindow::togglePause() +void +MainWindow::togglePause() { ui->actionPause->trigger(); } -void MainWindow::changeEvent(QEvent* event) +void +MainWindow::changeEvent(QEvent *event) { #ifdef Q_OS_WINDOWS - if (event->type() == QEvent::LanguageChange) - { + if (event->type() == QEvent::LanguageChange) { auto font_name = tr("FONT_NAME"); auto font_size = tr("FONT_SIZE"); QApplication::setFont(QFont(font_name, font_size.toInt())); @@ -2199,20 +2319,23 @@ void MainWindow::changeEvent(QEvent* event) } } -void MainWindow::on_actionRenderer_options_triggered() +void +MainWindow::on_actionRenderer_options_triggered() { auto dlg = ui->stackedWidget->getOptions(this); if (dlg) { if (dlg->exec() == QDialog::Accepted) { for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i] && renderers[i]->hasOptions()) renderers[i]->reloadOptions(); + if (renderers[i] && renderers[i]->hasOptions()) + renderers[i]->reloadOptions(); } } } } -void MainWindow::on_actionMCA_devices_triggered() +void +MainWindow::on_actionMCA_devices_triggered() { auto dlg = new MCADeviceList(this); @@ -2220,30 +2343,32 @@ void MainWindow::on_actionMCA_devices_triggered() dlg->exec(); } - -void MainWindow::on_actionShow_non_primary_monitors_triggered() +void +MainWindow::on_actionShow_non_primary_monitors_triggered() { - show_second_monitors = (int)ui->actionShow_non_primary_monitors->isChecked(); + show_second_monitors = (int) ui->actionShow_non_primary_monitors->isChecked(); blitDummied = true; if (show_second_monitors) { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - auto& secondaryRenderer = renderers[monitor_index]; - if (!renderers[monitor_index]) continue; + auto &secondaryRenderer = renderers[monitor_index]; + if (!renderers[monitor_index]) + continue; secondaryRenderer->show(); if (window_remember) { secondaryRenderer->setGeometry(monitor_settings[monitor_index].mon_window_x < 120 ? 120 : monitor_settings[monitor_index].mon_window_x, - monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, - monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, - monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); + monitor_settings[monitor_index].mon_window_y < 120 ? 120 : monitor_settings[monitor_index].mon_window_y, + monitor_settings[monitor_index].mon_window_w > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_w, + monitor_settings[monitor_index].mon_window_h > 2048 ? 2048 : monitor_settings[monitor_index].mon_window_h); } - secondaryRenderer->switchRenderer((RendererStack::Renderer)vid_api); + secondaryRenderer->switchRenderer((RendererStack::Renderer) vid_api); } } else { for (int monitor_index = 1; monitor_index < MONITORS_NUM; monitor_index++) { - auto& secondaryRenderer = renderers[monitor_index]; - if (!renderers[monitor_index]) continue; + auto &secondaryRenderer = renderers[monitor_index]; + if (!renderers[monitor_index]) + continue; secondaryRenderer->hide(); if (window_remember && renderers[monitor_index]) { monitor_settings[monitor_index].mon_window_w = renderers[monitor_index]->geometry().width(); @@ -2257,15 +2382,15 @@ void MainWindow::on_actionShow_non_primary_monitors_triggered() blitDummied = false; } - -void MainWindow::on_actionOpen_screenshots_folder_triggered() +void +MainWindow::on_actionOpen_screenshots_folder_triggered() { QDir(QString(usr_path) + QString("/screenshots/")).mkpath("."); QDesktopServices::openUrl(QUrl(QString("file:///") + usr_path + QString("/screenshots/"))); } - -void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked) +void +MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked) { video_fullscreen_scale_maximized = checked; @@ -2273,10 +2398,10 @@ void MainWindow::on_actionApply_fullscreen_stretch_mode_when_maximized_triggered ui->stackedWidget->onResize(widget->width(), widget->height()); for (int i = 1; i < MONITORS_NUM; i++) { - if (renderers[i]) renderers[i]->onResize(renderers[i]->width(), renderers[i]->height()); + if (renderers[i]) + renderers[i]->onResize(renderers[i]->width(), renderers[i]->height()); } device_force_redraw(); config_save(); } - diff --git a/src/qt/qt_mainwindow.hpp b/src/qt/qt_mainwindow.hpp index 692b9c3f0..6ad4c9beb 100644 --- a/src/qt/qt_mainwindow.hpp +++ b/src/qt/qt_mainwindow.hpp @@ -20,27 +20,26 @@ class MainWindow; class MachineStatus; -class MainWindow : public QMainWindow -{ +class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); - void showMessage(int flags, const QString& header, const QString& message); - void getTitle(wchar_t* title); - void blitToWidget(int x, int y, int w, int h, int monitor_index); + void showMessage(int flags, const QString &header, const QString &message); + void getTitle(wchar_t *title); + void blitToWidget(int x, int y, int w, int h, int monitor_index); QSize getRenderWidgetSize(); - void setSendKeyboardInput(bool enabled); + void setSendKeyboardInput(bool enabled); std::array, 8> renderers; signals: - void paint(const QImage& image); + void paint(const QImage &image); void resizeContents(int w, int h); void resizeContentsMonitor(int w, int h, int monitor_index); void pollMouse(); - void statusBarMessage(const QString& msg); + void statusBarMessage(const QString &msg); void updateStatusBarPanes(); void updateStatusBarActivity(int tag, bool active); void updateStatusBarEmpty(int tag, bool empty); @@ -52,12 +51,12 @@ signals: void initRendererMonitorForNonQtThread(int monitor_index); void destroyRendererMonitorForNonQtThread(int monitor_index); - void setTitle(const QString& title); + void setTitle(const QString &title); void setFullscreen(bool state); void setMouseCapture(bool state); - void showMessageForNonQtThread(int flags, const QString& header, const QString& message); - void getTitleForNonQtThread(wchar_t* title); + void showMessageForNonQtThread(int flags, const QString &header, const QString &message); + void getTitleForNonQtThread(wchar_t *title); public slots: void showSettings(); void hardReset(); @@ -120,43 +119,43 @@ private slots: void on_actionRenderer_options_triggered(); void refreshMediaMenu(); - void showMessage_(int flags, const QString& header, const QString& message); - void getTitle_(wchar_t* title); + void showMessage_(int flags, const QString &header, const QString &message); + void getTitle_(wchar_t *title); void on_actionMCA_devices_triggered(); protected: - void keyPressEvent(QKeyEvent* event) override; - void keyReleaseEvent(QKeyEvent* event) override; - void focusInEvent(QFocusEvent* event) override; - void focusOutEvent(QFocusEvent* event) override; - bool eventFilter(QObject* receiver, QEvent* event) override; - void showEvent(QShowEvent* event) override; - void closeEvent(QCloseEvent* event) override; - void changeEvent(QEvent* event) override; + void keyPressEvent(QKeyEvent *event) override; + void keyReleaseEvent(QKeyEvent *event) override; + void focusInEvent(QFocusEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + bool eventFilter(QObject *receiver, QEvent *event) override; + void showEvent(QShowEvent *event) override; + void closeEvent(QCloseEvent *event) override; + void changeEvent(QEvent *event) override; private slots: void on_actionShow_non_primary_monitors_triggered(); - void on_actionOpen_screenshots_folder_triggered(); + void on_actionOpen_screenshots_folder_triggered(); void on_actionApply_fullscreen_stretch_mode_when_maximized_triggered(bool checked); private: - Ui::MainWindow *ui; + Ui::MainWindow *ui; std::unique_ptr status; - std::shared_ptr mm; + std::shared_ptr mm; #ifdef Q_OS_MACOS uint32_t last_modifiers = 0; - void processMacKeyboardInput(bool down, const QKeyEvent* event); + void processMacKeyboardInput(bool down, const QKeyEvent *event); #endif /* If main window should send keyboard input */ bool send_keyboard_input = true; - bool shownonce = false; - bool resizableonce = false; - bool vnc_enabled = false; + bool shownonce = false; + bool resizableonce = false; + bool vnc_enabled = false; friend class SpecifyDimensions; friend class ProgSettings; diff --git a/src/qt/qt_mcadevicelist.cpp b/src/qt/qt_mcadevicelist.cpp index f1a39e358..95ae17f45 100644 --- a/src/qt/qt_mcadevicelist.cpp +++ b/src/qt/qt_mcadevicelist.cpp @@ -1,33 +1,27 @@ #include "qt_mcadevicelist.hpp" #include "ui_qt_mcadevicelist.h" -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/video.h> #include <86box/mca.h> #include <86box/plat.h> } -MCADeviceList::MCADeviceList(QWidget *parent) : - QDialog(parent), - ui(new Ui::MCADeviceList) +MCADeviceList::MCADeviceList(QWidget *parent) + : QDialog(parent) + , ui(new Ui::MCADeviceList) { ui->setupUi(this); startblit(); - if (mca_get_nr_cards() == 0) - { + if (mca_get_nr_cards() == 0) { ui->listWidget->addItem(QObject::tr("No MCA devices.")); ui->listWidget->setDisabled(true); - } - else - { - for (int i = 0; i < mca_get_nr_cards(); i++) - { + } else { + for (int i = 0; i < mca_get_nr_cards(); i++) { uint32_t deviceId = (mca_read_index(0x00, i) | (mca_read_index(0x01, i) << 8)); - if (deviceId != 0xFFFF) - { + if (deviceId != 0xFFFF) { QString hexRepresentation = QString::number(deviceId, 16).toUpper(); ui->listWidget->addItem(QString("Slot %1: 0x%2 (@%3.ADF)").arg(i + 1).arg(hexRepresentation, hexRepresentation)); } diff --git a/src/qt/qt_mcadevicelist.hpp b/src/qt/qt_mcadevicelist.hpp index e45992519..41b23c943 100644 --- a/src/qt/qt_mcadevicelist.hpp +++ b/src/qt/qt_mcadevicelist.hpp @@ -7,8 +7,7 @@ namespace Ui { class MCADeviceList; } -class MCADeviceList : public QDialog -{ +class MCADeviceList : public QDialog { Q_OBJECT public: diff --git a/src/qt/qt_mediahistorymanager.cpp b/src/qt/qt_mediahistorymanager.cpp index 19025d210..5564afd46 100644 --- a/src/qt/qt_mediahistorymanager.cpp +++ b/src/qt/qt_mediahistorymanager.cpp @@ -1,20 +1,19 @@ /* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* Media history management module -* -* -* -* Authors: cold-brewed -* -* Copyright 2022 The 86Box development team -*/ - + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Media history management module + * + * + * + * Authors: cold-brewed + * + * Copyright 2022 The 86Box development team + */ #include #include @@ -23,8 +22,7 @@ #include #include "qt_mediahistorymanager.hpp" -extern "C" -{ +extern "C" { #include <86box/timer.h> #include <86box/cdrom.h> #include <86box/fdd.h> @@ -32,23 +30,23 @@ extern "C" namespace ui { -MediaHistoryManager::MediaHistoryManager() { +MediaHistoryManager::MediaHistoryManager() +{ initializeImageHistory(); deserializeAllImageHistory(); initialDeduplication(); - } MediaHistoryManager::~MediaHistoryManager() -= default; + = default; master_list_t & MediaHistoryManager::blankImageHistory(master_list_t &initialized_master_list) const { - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { device_media_history_t device_media_history; // Loop for all possible media devices - for (int device_index = 0 ; device_index < maxDevicesSupported(device_type); device_index++) { + for (int device_index = 0; device_index < maxDevicesSupported(device_type); device_index++) { device_index_list_t indexing_list; device_media_history[device_index] = indexing_list; // Loop for each history slot @@ -61,12 +59,11 @@ MediaHistoryManager::blankImageHistory(master_list_t &initialized_master_list) c return initialized_master_list; } - -const device_index_list_t& +const device_index_list_t & MediaHistoryManager::getHistoryListForDeviceIndex(int index, ui::MediaType type) { if (master_list.contains(type)) { - if ((index >= 0 ) && (index < master_list[type].size())) { + if ((index >= 0) && (index < master_list[type].size())) { return master_list[type][index]; } else { qWarning("Media device index %i for device type %s was requested but index %i is out of range (valid range: >= 0 && < %i)", @@ -77,7 +74,8 @@ MediaHistoryManager::getHistoryListForDeviceIndex(int index, ui::MediaType type) return empty_device_index_list; } -void MediaHistoryManager::setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list) +void +MediaHistoryManager::setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list) { master_list[type][index] = std::move(history_list); } @@ -85,7 +83,7 @@ void MediaHistoryManager::setHistoryListForDeviceIndex(int index, ui::MediaType QString MediaHistoryManager::getImageForSlot(int index, int slot, ui::MediaType type) { - QString image_name; + QString image_name; device_index_list_t device_history = getHistoryListForDeviceIndex(index, type); if ((slot >= 0) && (slot < device_history.size())) { image_name = device_history[slot]; @@ -99,44 +97,47 @@ MediaHistoryManager::getImageForSlot(int index, int slot, ui::MediaType type) // These are hardcoded since we can't include the various // header files where they are defined (e.g., fdd.h, mo.h). // However, all in ui::MediaType support 4 except cassette. -int MediaHistoryManager::maxDevicesSupported(ui::MediaType type) +int +MediaHistoryManager::maxDevicesSupported(ui::MediaType type) { return type == ui::MediaType::Cassette ? 1 : 4; - } -void MediaHistoryManager::deserializeImageHistoryType(ui::MediaType type) +void +MediaHistoryManager::deserializeImageHistoryType(ui::MediaType type) { for (int device = 0; device < maxDevicesSupported(type); device++) { char **device_history_ptr = getEmuHistoryVarForType(type, device); - if(device_history_ptr == nullptr) { + if (device_history_ptr == nullptr) { // Device not supported, return and do not deserialize. // This will leave the image listing at the default initialization state // from the ui side (this class) continue; } - for ( int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { master_list[type][device][slot] = device_history_ptr[slot]; } } } -void MediaHistoryManager::deserializeAllImageHistory() +void +MediaHistoryManager::deserializeAllImageHistory() { - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { deserializeImageHistoryType(device_type); } } -void MediaHistoryManager::serializeImageHistoryType(ui::MediaType type) +void +MediaHistoryManager::serializeImageHistoryType(ui::MediaType type) { for (int device = 0; device < maxDevicesSupported(type); device++) { char **device_history_ptr = getEmuHistoryVarForType(type, device); - if(device_history_ptr == nullptr) { + if (device_history_ptr == nullptr) { // Device not supported, return and do not serialize. // This will leave the image listing at the current state, // and it will not be saved on the emu side continue; } - for ( int slot = 0; slot < MAX_PREV_IMAGES; slot++) { + for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { if (device_history_ptr[slot] != nullptr) { strncpy(device_history_ptr[slot], master_list[type][device][slot].toUtf8().constData(), MAX_IMAGE_PATH_LEN); } @@ -144,19 +145,21 @@ void MediaHistoryManager::serializeImageHistoryType(ui::MediaType type) } } -void MediaHistoryManager::serializeAllImageHistory() +void +MediaHistoryManager::serializeAllImageHistory() { - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { serializeImageHistoryType(device_type); } } -void MediaHistoryManager::initialDeduplication() +void +MediaHistoryManager::initialDeduplication() { QString current_image; // Perform initial dedup if an image is loaded - for ( const auto device_type : ui::AllSupportedMediaHistoryTypes ) { + for (const auto device_type : ui::AllSupportedMediaHistoryTypes) { for (int device_index = 0; device_index < maxDevicesSupported(device_type); device_index++) { device_index_list_t device_history = getHistoryListForDeviceIndex(device_index, device_type); switch (device_type) { @@ -170,10 +173,10 @@ void MediaHistoryManager::initialDeduplication() continue; break; } - deduplicateList(device_history, QVector (1, current_image)); + deduplicateList(device_history, QVector(1, current_image)); // Fill in missing, if any int missing = MAX_PREV_IMAGES - device_history.size(); - if(missing) { + if (missing) { for (int i = 0; i < missing; i++) { device_history.push_back(QString()); } @@ -183,7 +186,8 @@ void MediaHistoryManager::initialDeduplication() } } -char ** MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index) +char ** +MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int index) { switch (type) { case ui::MediaType::Optical: @@ -192,24 +196,23 @@ char ** MediaHistoryManager::getEmuHistoryVarForType(ui::MediaType type, int ind return &fdd_image_history[index][0]; default: return nullptr; - } } device_index_list_t & -MediaHistoryManager::deduplicateList(device_index_list_t &device_history, const QVector& filenames) +MediaHistoryManager::deduplicateList(device_index_list_t &device_history, const QVector &filenames) { QVector items_to_delete; for (auto &list_item_path : device_history) { - if(list_item_path.isEmpty()) { - continue ; + if (list_item_path.isEmpty()) { + continue; } - for (const auto& path_to_check : filenames) { - if(path_to_check.isEmpty()) { - continue ; + for (const auto &path_to_check : filenames) { + if (path_to_check.isEmpty()) { + continue; } QString adjusted_path = pathAdjustSingle(path_to_check); - int match = QString::localeAwareCompare(list_item_path, adjusted_path); + int match = QString::localeAwareCompare(list_item_path, adjusted_path); if (match == 0) { items_to_delete.append(list_item_path); } @@ -217,22 +220,22 @@ MediaHistoryManager::deduplicateList(device_index_list_t &device_history, const } // Remove by name rather than index because the index would change // after each removal - for (const auto& path: items_to_delete) { + for (const auto &path : items_to_delete) { device_history.removeAll(path); } return device_history; } -void MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const QString& image_name, const QString& new_image_name) +void +MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const QString &image_name, const QString &new_image_name) { device_index_list_t device_history = getHistoryListForDeviceIndex(index, type); - QVector files_to_check; + QVector files_to_check; files_to_check.append(image_name); files_to_check.append(new_image_name); device_history = deduplicateList(device_history, files_to_check); - if (!image_name.isEmpty()) { device_history.push_front(image_name); } @@ -244,7 +247,7 @@ void MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const // Fill in missing, if any int missing = MAX_PREV_IMAGES - device_history.size(); - if(missing) { + if (missing) { for (int i = 0; i < missing; i++) { device_history.push_back(QString()); } @@ -257,7 +260,8 @@ void MediaHistoryManager::addImageToHistory(int index, ui::MediaType type, const serializeImageHistoryType(type); } -QString MediaHistoryManager::mediaTypeToString(ui::MediaType type) +QString +MediaHistoryManager::mediaTypeToString(ui::MediaType type) { QMetaEnum qme = QMetaEnum::fromType(); return qme.valueToKey(static_cast(type)); @@ -266,7 +270,7 @@ QString MediaHistoryManager::mediaTypeToString(ui::MediaType type) QString MediaHistoryManager::pathAdjustSingle(QString checked_path) { - QString current_usr_path = getUsrPath(); + QString current_usr_path = getUsrPath(); QFileInfo file_info(checked_path); if (file_info.filePath().isEmpty() || current_usr_path.isEmpty() || file_info.isRelative()) { return checked_path; @@ -285,7 +289,8 @@ MediaHistoryManager::pathAdjustFull(device_index_list_t &device_history) } return device_history; } -QString MediaHistoryManager::getUsrPath() +QString +MediaHistoryManager::getUsrPath() { QString current_usr_path(usr_path); // Ensure `usr_path` has a trailing slash @@ -301,7 +306,7 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) } // For this check, explicitly prepend `usr_path` to relative paths to account for $CWD platform variances QFileInfo absolute_path = file_info.isRelative() ? QFileInfo(getUsrPath().append(file_info.filePath())) : file_info; - if(!absolute_path.exists()) { + if (!absolute_path.exists()) { qWarning("Image file %s does not exist - removing from history", qPrintable(file_info.filePath())); checked_path = ""; } @@ -309,7 +314,8 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history) return device_history; } -void MediaHistoryManager::initializeImageHistory() +void +MediaHistoryManager::initializeImageHistory() { auto initial_master_list = getMasterList(); setMasterList(blankImageHistory(initial_master_list)); diff --git a/src/qt/qt_mediahistorymanager.hpp b/src/qt/qt_mediahistorymanager.hpp index c628ce793..507cbdf7f 100644 --- a/src/qt/qt_mediahistorymanager.hpp +++ b/src/qt/qt_mediahistorymanager.hpp @@ -1,19 +1,19 @@ /* -* 86Box A hypervisor and IBM PC system emulator that specializes in -* running old operating systems and software designed for IBM -* PC systems and compatibles from 1981 through fairly recent -* system designs based on the PCI bus. -* -* This file is part of the 86Box distribution. -* -* Header for the media history management module -* -* -* -* Authors: cold-brewed -* -* Copyright 2022 The 86Box development team -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header for the media history management module + * + * + * + * Authors: cold-brewed + * + * Copyright 2022 The 86Box development team + */ #ifndef QT_MEDIAHISTORYMANAGER_HPP #define QT_MEDIAHISTORYMANAGER_HPP @@ -30,110 +30,109 @@ extern "C" { // This macro helps give us the required `qHash()` function in order to use the // enum as a hash key -#define QHASH_FOR_CLASS_ENUM(T) \ -inline uint qHash(const T &t, uint seed) { \ - return ::qHash(static_cast::type>(t), seed); \ -} +#define QHASH_FOR_CLASS_ENUM(T) \ + inline uint qHash(const T &t, uint seed) \ + { \ + return ::qHash(static_cast::type>(t), seed); \ + } typedef QVector device_index_list_t; typedef QHash> device_media_history_t; - namespace ui { - Q_NAMESPACE - - enum class MediaType { - Floppy, - Optical, - Zip, - Mo, - Cassette - }; - // This macro allows us to do a reverse lookup of the enum with `QMetaEnum` - Q_ENUM_NS(MediaType) - - QHASH_FOR_CLASS_ENUM(MediaType) +Q_NAMESPACE - typedef QHash master_list_t; +enum class MediaType { + Floppy, + Optical, + Zip, + Mo, + Cassette +}; +// This macro allows us to do a reverse lookup of the enum with `QMetaEnum` +Q_ENUM_NS(MediaType) - // Used to iterate over all supported types when preparing data structures - // Also useful to indicate which types support history - static const MediaType AllSupportedMediaHistoryTypes[] = { - MediaType::Optical, - MediaType::Floppy, - }; +QHASH_FOR_CLASS_ENUM(MediaType) - class MediaHistoryManager { +typedef QHash master_list_t; - public: - MediaHistoryManager(); - virtual ~MediaHistoryManager(); +// Used to iterate over all supported types when preparing data structures +// Also useful to indicate which types support history +static const MediaType AllSupportedMediaHistoryTypes[] = { + MediaType::Optical, + MediaType::Floppy, +}; - // Get the image name for a particular slot, - // index, and type combination - QString getImageForSlot(int index, int slot, ui::MediaType type); +class MediaHistoryManager { - // Add an image to history - void addImageToHistory(int index, ui::MediaType type, const QString& image_name, const QString& new_image_name); +public: + MediaHistoryManager(); + virtual ~MediaHistoryManager(); - // Convert the enum value to a string - static QString mediaTypeToString(ui::MediaType type); + // Get the image name for a particular slot, + // index, and type combination + QString getImageForSlot(int index, int slot, ui::MediaType type); - // Clear out the image history - void clearImageHistory(); + // Add an image to history + void addImageToHistory(int index, ui::MediaType type, const QString &image_name, const QString &new_image_name); + // Convert the enum value to a string + static QString mediaTypeToString(ui::MediaType type); - private: - int max_images = MAX_PREV_IMAGES; + // Clear out the image history + void clearImageHistory(); - // Main hash of hash of vector of strings - master_list_t master_list; - [[nodiscard]] const master_list_t &getMasterList() const; - void setMasterList(const master_list_t &masterList); +private: + int max_images = MAX_PREV_IMAGES; - device_index_list_t index_list, empty_device_index_list; + // Main hash of hash of vector of strings + master_list_t master_list; + [[nodiscard]] const master_list_t &getMasterList() const; + void setMasterList(const master_list_t &masterList); - // Return a blank, initialized image history list - master_list_t &blankImageHistory(master_list_t &initialized_master_list) const; + device_index_list_t index_list, empty_device_index_list; - // Initialize the image history - void initializeImageHistory(); + // Return a blank, initialized image history list + master_list_t &blankImageHistory(master_list_t &initialized_master_list) const; - // Max number of devices supported by media type - static int maxDevicesSupported(ui::MediaType type); + // Initialize the image history + void initializeImageHistory(); - // Serialize the data back into the C array - // on the emu side - void serializeImageHistoryType(ui::MediaType type); - void serializeAllImageHistory(); + // Max number of devices supported by media type + static int maxDevicesSupported(ui::MediaType type); - // Deserialize the data from C array on the emu side - // for the ui side - void deserializeImageHistoryType(ui::MediaType type); - void deserializeAllImageHistory(); + // Serialize the data back into the C array + // on the emu side + void serializeImageHistoryType(ui::MediaType type); + void serializeAllImageHistory(); - // Get emu history variable for a device type - static char** getEmuHistoryVarForType(ui::MediaType type, int index); + // Deserialize the data from C array on the emu side + // for the ui side + void deserializeImageHistoryType(ui::MediaType type); + void deserializeAllImageHistory(); - // Get or set the history for a specific device/index combo - const device_index_list_t &getHistoryListForDeviceIndex(int index, ui::MediaType type); - void setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list); + // Get emu history variable for a device type + static char **getEmuHistoryVarForType(ui::MediaType type, int index); - // Remove missing image files from history list - static device_index_list_t &removeMissingImages(device_index_list_t &device_history); + // Get or set the history for a specific device/index combo + const device_index_list_t &getHistoryListForDeviceIndex(int index, ui::MediaType type); + void setHistoryListForDeviceIndex(int index, ui::MediaType type, device_index_list_t history_list); - // If an absolute path is contained within `usr_path`, convert to a relative path - static device_index_list_t &pathAdjustFull(device_index_list_t &device_history); - static QString pathAdjustSingle(QString checked_path); + // Remove missing image files from history list + static device_index_list_t &removeMissingImages(device_index_list_t &device_history); - // Deduplicate history entries - static device_index_list_t &deduplicateList(device_index_list_t &device_history, const QVector& filenames); - void initialDeduplication(); + // If an absolute path is contained within `usr_path`, convert to a relative path + static device_index_list_t &pathAdjustFull(device_index_list_t &device_history); + static QString pathAdjustSingle(QString checked_path); - // Gets the `usr_path` from the emu side and appends a - // trailing slash if necessary - static QString getUsrPath(); - }; + // Deduplicate history entries + static device_index_list_t &deduplicateList(device_index_list_t &device_history, const QVector &filenames); + void initialDeduplication(); + + // Gets the `usr_path` from the emu side and appends a + // trailing slash if necessary + static QString getUsrPath(); +}; } // ui diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index 159c33b39..e0c145981 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -47,7 +47,6 @@ extern "C" { #include <86box/ui.h> #include <86box/thread.h> #include <86box/network.h> - }; #include "qt_newfloppydialog.hpp" @@ -58,14 +57,18 @@ extern "C" { std::shared_ptr MediaMenu::ptr; -MediaMenu::MediaMenu(QWidget* parent) : QObject(parent) { +MediaMenu::MediaMenu(QWidget *parent) + : QObject(parent) +{ parentWidget = parent; } -void MediaMenu::refresh(QMenu *parentMenu) { +void +MediaMenu::refresh(QMenu *parentMenu) +{ parentMenu->clear(); - if(MachineStatus::hasCassette()) { + if (MachineStatus::hasCassette()) { cassetteMenu = parentMenu->addMenu(""); cassetteMenu->addAction(tr("&New image..."), [this]() { cassetteNewImage(); }); cassetteMenu->addSeparator(); @@ -88,8 +91,8 @@ void MediaMenu::refresh(QMenu *parentMenu) { cartridgeMenus.clear(); if (machine_has_cartridge(machine)) { - for(int i = 0; i < 2; i++) { - auto* menu = parentMenu->addMenu(""); + for (int i = 0; i < 2; i++) { + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&Image..."), [this, i]() { cartridgeSelectImage(i); }); menu->addSeparator(); cartridgeEjectPos = menu->children().count(); @@ -101,7 +104,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { floppyMenus.clear(); MachineStatus::iterateFDD([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&New image..."), [this, i]() { floppyNewImage(i); }); menu->addSeparator(); menu->addAction(tr("&Existing image..."), [this, i]() { floppySelectImage(i, false); }); @@ -123,7 +126,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { cdromMenus.clear(); MachineStatus::iterateCDROM([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); cdromMutePos = menu->children().count(); menu->addAction(QApplication::style()->standardIcon(QStyle::SP_MediaVolumeMuted), tr("&Mute"), [this, i]() { cdromMute(i); })->setCheckable(true); menu->addSeparator(); @@ -136,7 +139,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { } menu->addSeparator(); cdromImagePos = menu->children().count(); - cdromDirPos = menu->children().count(); + cdromDirPos = menu->children().count(); menu->addAction(tr("E&ject"), [this, i]() { cdromEject(i); })->setCheckable(false); cdromMenus[i] = menu; cdromUpdateMenu(i); @@ -144,7 +147,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { zipMenus.clear(); MachineStatus::iterateZIP([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&New image..."), [this, i]() { zipNewImage(i); }); menu->addSeparator(); menu->addAction(tr("&Existing image..."), [this, i]() { zipSelectImage(i, false); }); @@ -160,7 +163,7 @@ void MediaMenu::refresh(QMenu *parentMenu) { moMenus.clear(); MachineStatus::iterateMO([this, parentMenu](int i) { - auto* menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); menu->addAction(tr("&New image..."), [this, i]() { moNewImage(i); }); menu->addSeparator(); menu->addAction(tr("&Existing image..."), [this, i]() { moSelectImage(i, false); }); @@ -176,9 +179,9 @@ void MediaMenu::refresh(QMenu *parentMenu) { netMenus.clear(); MachineStatus::iterateNIC([this, parentMenu](int i) { - auto *menu = parentMenu->addMenu(""); + auto *menu = parentMenu->addMenu(""); netDisconnPos = menu->children().count(); - auto *action = menu->addAction(tr("&Connected"), [this, i] { network_is_connected(i) ? nicDisconnect(i) : nicConnect(i); }); + auto *action = menu->addAction(tr("&Connected"), [this, i] { network_is_connected(i) ? nicDisconnect(i) : nicConnect(i); }); action->setCheckable(true); netMenus[i] = menu; nicUpdateMenu(i); @@ -186,36 +189,42 @@ void MediaMenu::refresh(QMenu *parentMenu) { parentMenu->addAction(tr("Clear image history"), [this]() { clearImageHistory(); }); } -void MediaMenu::cassetteNewImage() { - auto filename = QFileDialog::getSaveFileName(parentWidget, tr("Create...")); +void +MediaMenu::cassetteNewImage() +{ + auto filename = QFileDialog::getSaveFileName(parentWidget, tr("Create...")); QFileInfo fileinfo(filename); if (fileinfo.suffix().isEmpty()) { filename.append(".cas"); } if (!filename.isNull()) { - if (filename.isEmpty()) cassetteEject(); - else cassetteMount(filename, false); + if (filename.isEmpty()) + cassetteEject(); + else + cassetteMount(filename, false); } } -void MediaMenu::cassetteSelectImage(bool wp) { +void +MediaMenu::cassetteSelectImage(bool wp) +{ auto filename = QFileDialog::getOpenFileName(parentWidget, - QString(), - getMediaOpenDirectory(), - tr("Cassette images") % - util::DlgFilter({ "pcm","raw","wav","cas" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + QString(), + getMediaOpenDirectory(), + tr("Cassette images") % util::DlgFilter({ "pcm", "raw", "wav", "cas" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - if (!filename.isEmpty()) cassetteMount(filename, wp); + if (!filename.isEmpty()) + cassetteMount(filename, wp); } -void MediaMenu::cassetteMount(const QString& filename, bool wp) { +void +MediaMenu::cassetteMount(const QString &filename, bool wp) +{ pc_cas_set_fname(cassette, nullptr); memset(cassette_fname, 0, sizeof(cassette_fname)); cassette_ui_writeprot = wp ? 1 : 0; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); strncpy(cassette_fname, filenameBytes.data(), sizeof(cassette_fname) - 1); pc_cas_set_fname(cassette, cassette_fname); @@ -227,7 +236,9 @@ void MediaMenu::cassetteMount(const QString& filename, bool wp) { config_save(); } -void MediaMenu::cassetteEject() { +void +MediaMenu::cassetteEject() +{ pc_cas_set_fname(cassette, nullptr); memset(cassette_fname, 0, sizeof(cassette_fname)); ui_sb_update_icon_state(SB_CASSETTE, 1); @@ -236,15 +247,17 @@ void MediaMenu::cassetteEject() { config_save(); } -void MediaMenu::cassetteUpdateMenu() { - QString name = cassette_fname; - QString mode = cassette_mode; - auto childs = cassetteMenu->children(); - auto* recordMenu = dynamic_cast(childs[cassetteRecordPos]); - auto* playMenu = dynamic_cast(childs[cassettePlayPos]); - auto* rewindMenu = dynamic_cast(childs[cassetteRewindPos]); - auto* fastFwdMenu = dynamic_cast(childs[cassetteFastFwdPos]); - auto* ejectMenu = dynamic_cast(childs[cassetteEjectPos]); +void +MediaMenu::cassetteUpdateMenu() +{ + QString name = cassette_fname; + QString mode = cassette_mode; + auto childs = cassetteMenu->children(); + auto *recordMenu = dynamic_cast(childs[cassetteRecordPos]); + auto *playMenu = dynamic_cast(childs[cassettePlayPos]); + auto *rewindMenu = dynamic_cast(childs[cassetteRewindPos]); + auto *fastFwdMenu = dynamic_cast(childs[cassetteFastFwdPos]); + auto *ejectMenu = dynamic_cast(childs[cassetteEjectPos]); recordMenu->setEnabled(!name.isEmpty()); playMenu->setEnabled(!name.isEmpty()); @@ -254,12 +267,13 @@ void MediaMenu::cassetteUpdateMenu() { bool isSaving = mode == QStringLiteral("save"); recordMenu->setChecked(isSaving); - playMenu->setChecked(! isSaving); + playMenu->setChecked(!isSaving); cassetteMenu->setTitle(QString::asprintf(tr("Cassette: %s").toUtf8().constData(), (name.isEmpty() ? tr("(empty)") : name).toUtf8().constData())); } -void MediaMenu::cartridgeMount(int i, const QString &filename) +void +MediaMenu::cartridgeMount(int i, const QString &filename) { cart_close(i); QByteArray filenameBytes = filename.toUtf8(); @@ -271,15 +285,14 @@ void MediaMenu::cartridgeMount(int i, const QString &filename) config_save(); } -void MediaMenu::cartridgeSelectImage(int i) { +void +MediaMenu::cartridgeSelectImage(int i) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), - tr("Cartridge images") % - util::DlgFilter({ "a","b","jrc" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + tr("Cartridge images") % util::DlgFilter({ "a", "b", "jrc" }) % tr("All files") % util::DlgFilter({ "*" }, true)); if (filename.isEmpty()) { return; @@ -287,7 +300,9 @@ void MediaMenu::cartridgeSelectImage(int i) { cartridgeMount(i, filename); } -void MediaMenu::cartridgeEject(int i) { +void +MediaMenu::cartridgeEject(int i) +{ cart_close(i); ui_sb_update_icon_state(SB_CARTRIDGE | i, 1); cartridgeUpdateMenu(i); @@ -295,27 +310,33 @@ void MediaMenu::cartridgeEject(int i) { config_save(); } -void MediaMenu::cartridgeUpdateMenu(int i) { - QString name = cart_fns[i]; - auto* menu = cartridgeMenus[i]; - auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); +void +MediaMenu::cartridgeUpdateMenu(int i) +{ + QString name = cart_fns[i]; + auto *menu = cartridgeMenus[i]; + auto childs = menu->children(); + auto *ejectMenu = dynamic_cast(childs[cartridgeEjectPos]); ejectMenu->setEnabled(!name.isEmpty()); - //menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name)); + // menu->setTitle(tr("Cartridge %1: %2").arg(QString::number(i+1), name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("Cartridge %i: %ls").toUtf8().constData(), i + 1, name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::floppyNewImage(int i) { +void +MediaMenu::floppyNewImage(int i) +{ NewFloppyDialog dialog(NewFloppyDialog::MediaType::Floppy, parentWidget); switch (dialog.exec()) { - case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); - floppyMount(i, filename, false); - break; + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + floppyMount(i, filename, false); + break; } } -void MediaMenu::floppySelectImage(int i, bool wp) { +void +MediaMenu::floppySelectImage(int i, bool wp) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), @@ -336,11 +357,13 @@ void MediaMenu::floppySelectImage(int i, bool wp) { if (!filename.isEmpty()) floppyMount(i, filename, wp); } -void MediaMenu::floppyMount(int i, const QString &filename, bool wp) { +void +MediaMenu::floppyMount(int i, const QString &filename, bool wp) +{ auto previous_image = QFileInfo(floppyfns[i]); fdd_close(i); ui_writeprot[i] = wp ? 1 : 0; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); fdd_load(i, filenameBytes.data()); } @@ -351,7 +374,9 @@ void MediaMenu::floppyMount(int i, const QString &filename, bool wp) { config_save(); } -void MediaMenu::floppyEject(int i) { +void +MediaMenu::floppyEject(int i) +{ mhm.addImageToHistory(i, ui::MediaType::Floppy, floppyfns[i], QString()); fdd_close(i); ui_sb_update_icon_state(SB_FLOPPY | i, 1); @@ -360,9 +385,11 @@ void MediaMenu::floppyEject(int i) { config_save(); } -void MediaMenu::floppyExportTo86f(int i) { +void +MediaMenu::floppyExportTo86f(int i) +{ auto filename = QFileDialog::getSaveFileName(parentWidget, QString(), QString(), tr("Surface images") % util::DlgFilter({ "86f" }, true)); - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); plat_pause(1); if (d86f_export(i, filenameBytes.data()) == 0) { @@ -372,20 +399,22 @@ void MediaMenu::floppyExportTo86f(int i) { } } -void MediaMenu::floppyUpdateMenu(int i) { - QString name = floppyfns[i]; +void +MediaMenu::floppyUpdateMenu(int i) +{ + QString name = floppyfns[i]; QFileInfo fi(floppyfns[i]); if (!floppyMenus.contains(i)) return; - auto* menu = floppyMenus[i]; - auto childs = menu->children(); + auto *menu = floppyMenus[i]; + auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[floppyEjectPos]); - auto* exportMenu = dynamic_cast(childs[floppyExportPos]); + auto *ejectMenu = dynamic_cast(childs[floppyEjectPos]); + auto *exportMenu = dynamic_cast(childs[floppyExportPos]); ejectMenu->setEnabled(!name.isEmpty()); - ejectMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData())); + ejectMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData())); exportMenu->setEnabled(!name.isEmpty()); for (int slot = 0; slot < MAX_PREV_IMAGES; slot++) { @@ -393,25 +422,30 @@ void MediaMenu::floppyUpdateMenu(int i) { } int type = fdd_get_type(i); - //floppyMenus[i]->setTitle(tr("Floppy %1 (%2): %3").arg(QString::number(i+1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); + // floppyMenus[i]->setTitle(tr("Floppy %1 (%2): %3").arg(QString::number(i+1), fdd_getname(type), name.isEmpty() ? tr("(empty)") : name)); floppyMenus[i]->setTitle(QString::asprintf(tr("Floppy %i (%s): %ls").toUtf8().constData(), i + 1, fdd_getname(type), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::floppyMenuSelect(int index, int slot) { +void +MediaMenu::floppyMenuSelect(int index, int slot) +{ QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Floppy); floppyMount(index, filename.toUtf8().constData(), false); floppyUpdateMenu(index); ui_sb_update_tip(SB_FLOPPY | index); } -void MediaMenu::cdromMute(int i) { +void +MediaMenu::cdromMute(int i) +{ cdrom[i].sound_on ^= 1; config_save(); cdromUpdateMenu(i); sound_cd_thread_reset(); } -void MediaMenu::cdromMount(int i, const QString &filename) +void +MediaMenu::cdromMount(int i, const QString &filename) { QByteArray fn = filename.toUtf8().data(); @@ -438,8 +472,10 @@ void MediaMenu::cdromMount(int i, const QString &filename) config_save(); } -void MediaMenu::cdromMount(int i, int dir) { - QString filename; +void +MediaMenu::cdromMount(int i, int dir) +{ + QString filename; QFileInfo fi(cdrom[i].image_path); if (dir) { @@ -450,10 +486,7 @@ void MediaMenu::cdromMount(int i, int dir) { parentWidget, QString(), QString(), - tr("CD-ROM images") % - util::DlgFilter({ "iso","cue" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + tr("CD-ROM images") % util::DlgFilter({ "iso", "cue" }) % tr("All files") % util::DlgFilter({ "*" }, true)); } if (filename.isEmpty()) { @@ -463,34 +496,40 @@ void MediaMenu::cdromMount(int i, int dir) { cdromMount(i, filename); } -void MediaMenu::cdromEject(int i) { +void +MediaMenu::cdromEject(int i) +{ mhm.addImageToHistory(i, ui::MediaType::Optical, cdrom[i].image_path, QString()); cdrom_eject(i); cdromUpdateMenu(i); ui_sb_update_tip(SB_CDROM | i); } -void MediaMenu::cdromReload(int index, int slot) { +void +MediaMenu::cdromReload(int index, int slot) +{ QString filename = mhm.getImageForSlot(index, slot, ui::MediaType::Optical); cdromMount(index, filename.toUtf8().constData()); cdromUpdateMenu(index); ui_sb_update_tip(SB_CDROM | index); } -void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { - QMenu* menu; - QAction* imageHistoryUpdatePos; +void +MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) +{ + QMenu *menu; + QAction *imageHistoryUpdatePos; QObjectList children; - QFileInfo fi; - QIcon menu_icon; + QFileInfo fi; + QIcon menu_icon; switch (type) { case ui::MediaType::Optical: if (!cdromMenus.contains(index)) return; - menu = cdromMenus[index]; - children = menu->children(); - imageHistoryUpdatePos = dynamic_cast(children[cdromImageHistoryPos[slot]]); + menu = cdromMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[cdromImageHistoryPos[slot]]); fi.setFile(mhm.getImageForSlot(index, slot, type)); menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); imageHistoryUpdatePos->setIcon(menu_icon); @@ -498,9 +537,9 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { case ui::MediaType::Floppy: if (!floppyMenus.contains(index)) return; - menu = floppyMenus[index]; - children = menu->children(); - imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); + menu = floppyMenus[index]; + children = menu->children(); + imageHistoryUpdatePos = dynamic_cast(children[floppyImageHistoryPos[slot]]); fi.setFile(mhm.getImageForSlot(index, slot, type)); break; default: @@ -514,27 +553,31 @@ void MediaMenu::updateImageHistory(int index, int slot, ui::MediaType type) { imageHistoryUpdatePos->setVisible(fi.exists()); } -void MediaMenu::clearImageHistory() { +void +MediaMenu::clearImageHistory() +{ mhm.clearImageHistory(); ui_sb_update_panes(); } -void MediaMenu::cdromUpdateMenu(int i) { - QString name = cdrom[i].image_path; +void +MediaMenu::cdromUpdateMenu(int i) +{ + QString name = cdrom[i].image_path; QFileInfo fi(cdrom[i].image_path); if (!cdromMenus.contains(i)) return; - auto* menu = cdromMenus[i]; - auto childs = menu->children(); + auto *menu = cdromMenus[i]; + auto childs = menu->children(); - auto* muteMenu = dynamic_cast(childs[cdromMutePos]); + auto *muteMenu = dynamic_cast(childs[cdromMutePos]); muteMenu->setChecked(cdrom[i].sound_on == 0); - auto* imageMenu = dynamic_cast(childs[cdromImagePos]); + auto *imageMenu = dynamic_cast(childs[cdromImagePos]); imageMenu->setEnabled(!name.isEmpty()); QString menu_item_name = name.isEmpty() ? QString().toUtf8().constData() : fi.fileName().toUtf8().constData(); - auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); + auto menu_icon = fi.isDir() ? QApplication::style()->standardIcon(QStyle::SP_DirIcon) : ProgSettings::loadIcon("/cdrom.ico"); imageMenu->setIcon(menu_icon); imageMenu->setText(QString::asprintf(tr("Eject %s").toUtf8().constData(), menu_item_name.toUtf8().constData())); @@ -544,47 +587,51 @@ void MediaMenu::cdromUpdateMenu(int i) { QString busName = tr("Unknown Bus"); switch (cdrom[i].bus_type) { - case CDROM_BUS_ATAPI: - busName = "ATAPI"; - break; - case CDROM_BUS_SCSI: - busName = "SCSI"; - break; + case CDROM_BUS_ATAPI: + busName = "ATAPI"; + break; + case CDROM_BUS_SCSI: + busName = "SCSI"; + break; } - //menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); + // menu->setTitle(tr("CD-ROM %1 (%2): %3").arg(QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("CD-ROM %i (%s): %s").toUtf8().constData(), i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toUtf8().data() : name.toUtf8().data())); } -void MediaMenu::zipNewImage(int i) { +void +MediaMenu::zipNewImage(int i) +{ NewFloppyDialog dialog(NewFloppyDialog::MediaType::Zip, parentWidget); switch (dialog.exec()) { - case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); - zipMount(i, filename, false); - break; + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + zipMount(i, filename, false); + break; } } -void MediaMenu::zipSelectImage(int i, bool wp) { +void +MediaMenu::zipSelectImage(int i, bool wp) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), QString(), - tr("ZIP images") % - util::DlgFilter({ "im?","zdi" }) % - tr("All files") % - util::DlgFilter({ "*" }, true)); + tr("ZIP images") % util::DlgFilter({ "im?", "zdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - if (!filename.isEmpty()) zipMount(i, filename, wp); + if (!filename.isEmpty()) + zipMount(i, filename, wp); } -void MediaMenu::zipMount(int i, const QString &filename, bool wp) { +void +MediaMenu::zipMount(int i, const QString &filename, bool wp) +{ zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_close(dev); zip_drives[i].read_only = wp; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); zip_load(dev, filenameBytes.data()); zip_insert(dev); @@ -597,7 +644,9 @@ void MediaMenu::zipMount(int i, const QString &filename, bool wp) { config_save(); } -void MediaMenu::zipEject(int i) { +void +MediaMenu::zipEject(int i) +{ zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_close(dev); @@ -613,78 +662,89 @@ void MediaMenu::zipEject(int i) { config_save(); } -void MediaMenu::zipReload(int i) { +void +MediaMenu::zipReload(int i) +{ zip_t *dev = (zip_t *) zip_drives[i].priv; zip_disk_reload(dev); if (strlen(zip_drives[i].image_path) == 0) { - ui_sb_update_icon_state(SB_ZIP|i, 1); + ui_sb_update_icon_state(SB_ZIP | i, 1); } else { - ui_sb_update_icon_state(SB_ZIP|i, 0); + ui_sb_update_icon_state(SB_ZIP | i, 0); } zipUpdateMenu(i); - ui_sb_update_tip(SB_ZIP|i); + ui_sb_update_tip(SB_ZIP | i); config_save(); } -void MediaMenu::zipUpdateMenu(int i) { - QString name = zip_drives[i].image_path; +void +MediaMenu::zipUpdateMenu(int i) +{ + QString name = zip_drives[i].image_path; QString prev_name = zip_drives[i].prev_image_path; if (!zipMenus.contains(i)) return; - auto* menu = zipMenus[i]; - auto childs = menu->children(); + auto *menu = zipMenus[i]; + auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[zipEjectPos]); - auto* reloadMenu = dynamic_cast(childs[zipReloadPos]); + auto *ejectMenu = dynamic_cast(childs[zipEjectPos]); + auto *reloadMenu = dynamic_cast(childs[zipReloadPos]); ejectMenu->setEnabled(!name.isEmpty()); reloadMenu->setEnabled(!prev_name.isEmpty()); QString busName = tr("Unknown Bus"); switch (zip_drives[i].bus_type) { - case ZIP_BUS_ATAPI: - busName = "ATAPI"; - break; - case ZIP_BUS_SCSI: - busName = "SCSI"; - break; + case ZIP_BUS_ATAPI: + busName = "ATAPI"; + break; + case ZIP_BUS_SCSI: + busName = "SCSI"; + break; } - //menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); + // menu->setTitle(tr("ZIP %1 %2 (%3): %4").arg((zip_drives[i].is_250 > 0) ? "250" : "100", QString::number(i+1), busName, name.isEmpty() ? tr("(empty)") : name)); menu->setTitle(QString::asprintf(tr("ZIP %03i %i (%s): %ls").toUtf8().constData(), (zip_drives[i].is_250 > 0) ? 250 : 100, i + 1, busName.toUtf8().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::moNewImage(int i) { +void +MediaMenu::moNewImage(int i) +{ NewFloppyDialog dialog(NewFloppyDialog::MediaType::Mo, parentWidget); switch (dialog.exec()) { - case QDialog::Accepted: - QByteArray filename = dialog.fileName().toUtf8(); - moMount(i, filename, false); - break; + case QDialog::Accepted: + QByteArray filename = dialog.fileName().toUtf8(); + moMount(i, filename, false); + break; } } -void MediaMenu::moSelectImage(int i, bool wp) { +void +MediaMenu::moSelectImage(int i, bool wp) +{ auto filename = QFileDialog::getOpenFileName( parentWidget, QString(), getMediaOpenDirectory(), - tr("MO images") % - util::DlgFilter({ "im?", "mdi" }) % - tr("All files") % - util::DlgFilter({ "*", }, true)); + tr("MO images") % util::DlgFilter({ "im?", "mdi" }) % tr("All files") % util::DlgFilter({ + "*", + }, + true)); - if (!filename.isEmpty()) moMount(i, filename, wp); + if (!filename.isEmpty()) + moMount(i, filename, wp); } -void MediaMenu::moMount(int i, const QString &filename, bool wp) { +void +MediaMenu::moMount(int i, const QString &filename, bool wp) +{ mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_close(dev); mo_drives[i].read_only = wp; - if (! filename.isEmpty()) { + if (!filename.isEmpty()) { QByteArray filenameBytes = filename.toUtf8(); mo_load(dev, filenameBytes.data()); mo_insert(dev); @@ -697,7 +757,9 @@ void MediaMenu::moMount(int i, const QString &filename, bool wp) { config_save(); } -void MediaMenu::moEject(int i) { +void +MediaMenu::moEject(int i) +{ mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_close(dev); @@ -713,63 +775,73 @@ void MediaMenu::moEject(int i) { config_save(); } -void MediaMenu::moReload(int i) { +void +MediaMenu::moReload(int i) +{ mo_t *dev = (mo_t *) mo_drives[i].priv; mo_disk_reload(dev); if (strlen(mo_drives[i].image_path) == 0) { - ui_sb_update_icon_state(SB_MO|i, 1); + ui_sb_update_icon_state(SB_MO | i, 1); } else { - ui_sb_update_icon_state(SB_MO|i, 0); + ui_sb_update_icon_state(SB_MO | i, 0); } moUpdateMenu(i); - ui_sb_update_tip(SB_MO|i); + ui_sb_update_tip(SB_MO | i); config_save(); } -void MediaMenu::moUpdateMenu(int i) { - QString name = mo_drives[i].image_path; +void +MediaMenu::moUpdateMenu(int i) +{ + QString name = mo_drives[i].image_path; QString prev_name = mo_drives[i].prev_image_path; if (!moMenus.contains(i)) return; - auto* menu = moMenus[i]; - auto childs = menu->children(); + auto *menu = moMenus[i]; + auto childs = menu->children(); - auto* ejectMenu = dynamic_cast(childs[moEjectPos]); - auto* reloadMenu = dynamic_cast(childs[moReloadPos]); + auto *ejectMenu = dynamic_cast(childs[moEjectPos]); + auto *reloadMenu = dynamic_cast(childs[moReloadPos]); ejectMenu->setEnabled(!name.isEmpty()); reloadMenu->setEnabled(!prev_name.isEmpty()); QString busName = tr("Unknown Bus"); switch (mo_drives[i].bus_type) { - case MO_BUS_ATAPI: - busName = "ATAPI"; - break; - case MO_BUS_SCSI: - busName = "SCSI"; - break; + case MO_BUS_ATAPI: + busName = "ATAPI"; + break; + case MO_BUS_SCSI: + busName = "SCSI"; + break; } menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } -void MediaMenu::nicConnect(int i) { +void +MediaMenu::nicConnect(int i) +{ network_connect(i, 1); - ui_sb_update_icon_state(SB_NETWORK|i, 0); + ui_sb_update_icon_state(SB_NETWORK | i, 0); nicUpdateMenu(i); config_save(); } -void MediaMenu::nicDisconnect(int i) { +void +MediaMenu::nicDisconnect(int i) +{ network_connect(i, 0); - ui_sb_update_icon_state(SB_NETWORK|i, 1); + ui_sb_update_icon_state(SB_NETWORK | i, 1); nicUpdateMenu(i); config_save(); } -void MediaMenu::nicUpdateMenu(int i) { +void +MediaMenu::nicUpdateMenu(int i) +{ if (!netMenus.contains(i)) return; @@ -785,15 +857,17 @@ void MediaMenu::nicUpdateMenu(int i) { QString devName = DeviceConfig::DeviceName(network_card_getdevice(net_cards_conf[i].device_num), network_card_get_internal_name(net_cards_conf[i].device_num), 1); - auto *menu = netMenus[i]; - auto childs = menu->children(); - auto *connectedAction = dynamic_cast(childs[netDisconnPos]); + auto *menu = netMenus[i]; + auto childs = menu->children(); + auto *connectedAction = dynamic_cast(childs[netDisconnPos]); connectedAction->setChecked(network_is_connected(i)); menu->setTitle(QString::asprintf(tr("NIC %02i (%ls) %ls").toUtf8().constData(), i + 1, netType.toStdU16String().data(), devName.toStdU16String().data())); } -QString MediaMenu::getMediaOpenDirectory() { +QString +MediaMenu::getMediaOpenDirectory() +{ QString openDirectory; if (open_dir_usr_path > 0) { openDirectory = QString::fromUtf8(usr_path); @@ -804,20 +878,27 @@ QString MediaMenu::getMediaOpenDirectory() { // callbacks from 86box C code extern "C" { -void zip_eject(uint8_t id) { +void +zip_eject(uint8_t id) +{ MediaMenu::ptr->zipEject(id); } -void zip_reload(uint8_t id) { +void +zip_reload(uint8_t id) +{ MediaMenu::ptr->zipReload(id); } -void mo_eject(uint8_t id) { +void +mo_eject(uint8_t id) +{ MediaMenu::ptr->moEject(id); } -void mo_reload(uint8_t id) { +void +mo_reload(uint8_t id) +{ MediaMenu::ptr->moReload(id); } - } diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 4cb177797..57fd8dfc2 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -10,13 +10,12 @@ extern "C" { } class QMenu; -class MediaMenu : QObject -{ +class MediaMenu : QObject { Q_OBJECT public: - MediaMenu(QWidget* parent); + MediaMenu(QWidget *parent); - void refresh(QMenu* parentMenu); + void refresh(QMenu *parentMenu); // because some 86box C-only code needs to call zip and // mo eject directly @@ -24,18 +23,18 @@ public: void cassetteNewImage(); void cassetteSelectImage(bool wp); - void cassetteMount(const QString& filename, bool wp); + void cassetteMount(const QString &filename, bool wp); void cassetteEject(); void cassetteUpdateMenu(); void cartridgeSelectImage(int i); - void cartridgeMount(int i, const QString& filename); + void cartridgeMount(int i, const QString &filename); void cartridgeEject(int i); void cartridgeUpdateMenu(int i); void floppyNewImage(int i); void floppySelectImage(int i, bool wp); - void floppyMount(int i, const QString& filename, bool wp); + void floppyMount(int i, const QString &filename, bool wp); void floppyEject(int i); void floppyMenuSelect(int index, int slot); void floppyExportTo86f(int i); @@ -43,7 +42,7 @@ public: void cdromMute(int i); void cdromMount(int i, int dir); - void cdromMount(int i, const QString& filename); + void cdromMount(int i, const QString &filename); void cdromEject(int i); void cdromReload(int index, int slot); void updateImageHistory(int index, int slot, ui::MediaType type); @@ -52,14 +51,14 @@ public: void zipNewImage(int i); void zipSelectImage(int i, bool wp); - void zipMount(int i, const QString& filename, bool wp); + void zipMount(int i, const QString &filename, bool wp); void zipEject(int i); void zipReload(int i); void zipUpdateMenu(int i); void moNewImage(int i); void moSelectImage(int i, bool wp); - void moMount(int i, const QString& filename, bool wp); + void moMount(int i, const QString &filename, bool wp); void moEject(int i); void moReload(int i); void moUpdateMenu(int i); @@ -67,18 +66,19 @@ public: void nicConnect(int i); void nicDisconnect(int i); void nicUpdateMenu(int i); + private: - QWidget* parentWidget = nullptr; + QWidget *parentWidget = nullptr; - QMenu* cassetteMenu = nullptr; - QMap cartridgeMenus; - QMap floppyMenus; - QMap cdromMenus; - QMap zipMenus; - QMap moMenus; - QMap netMenus; + QMenu *cassetteMenu = nullptr; + QMap cartridgeMenus; + QMap floppyMenus; + QMap cdromMenus; + QMap zipMenus; + QMap moMenus; + QMap netMenus; - QString getMediaOpenDirectory(); + QString getMediaOpenDirectory(); ui::MediaHistoryManager mhm; int cassetteRecordPos; diff --git a/src/qt/qt_midi.cpp b/src/qt/qt_midi.cpp index a9b741c9e..2ea8ad3b1 100644 --- a/src/qt/qt_midi.cpp +++ b/src/qt/qt_midi.cpp @@ -2,43 +2,65 @@ extern "C" { -void plat_midi_play_msg(uint8_t *msg) -{} +void +plat_midi_play_msg(uint8_t *msg) +{ +} -void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) -{} +void +plat_midi_play_sysex(uint8_t *sysex, unsigned int len) +{ +} -void plat_midi_input_init(void) -{} +void +plat_midi_input_init(void) +{ +} -void plat_midi_input_close(void) -{} +void +plat_midi_input_close(void) +{ +} -int plat_midi_write(uint8_t val) -{ return 0; } +int +plat_midi_write(uint8_t val) +{ + return 0; +} -void plat_midi_init() -{} +void +plat_midi_init() +{ +} -void plat_midi_close() -{} +void +plat_midi_close() +{ +} -int plat_midi_get_num_devs() -{ return 0; } +int +plat_midi_get_num_devs() +{ + return 0; +} -int plat_midi_in_get_num_devs(void) -{ return 0; } +int +plat_midi_in_get_num_devs(void) +{ + return 0; +} -void plat_midi_get_dev_name(int num, char *s) +void +plat_midi_get_dev_name(int num, char *s) { s[0] = ' '; s[1] = 0; } -void plat_midi_in_get_dev_name(int num, char *s) +void +plat_midi_in_get_dev_name(int num, char *s) { s[0] = ' '; s[1] = 0; } - } diff --git a/src/qt/qt_models_common.cpp b/src/qt/qt_models_common.cpp index eaa14bc0d..0e9856a50 100644 --- a/src/qt/qt_models_common.cpp +++ b/src/qt/qt_models_common.cpp @@ -18,7 +18,8 @@ #include -int Models::AddEntry(QAbstractItemModel *model, const QString& displayRole, int userRole) +int +Models::AddEntry(QAbstractItemModel *model, const QString &displayRole, int userRole) { int row = model->rowCount(); model->insertRow(row); diff --git a/src/qt/qt_models_common.hpp b/src/qt/qt_models_common.hpp index 91cda3836..98674a68f 100644 --- a/src/qt/qt_models_common.hpp +++ b/src/qt/qt_models_common.hpp @@ -2,7 +2,6 @@ class QString; class QAbstractItemModel; -namespace Models -{ - int AddEntry(QAbstractItemModel* model, const QString& displayRole, int userRole); +namespace Models { +int AddEntry(QAbstractItemModel *model, const QString &displayRole, int userRole); }; diff --git a/src/qt/qt_newfloppydialog.cpp b/src/qt/qt_newfloppydialog.cpp index 1581c6e52..1cb81d2ce 100644 --- a/src/qt/qt_newfloppydialog.cpp +++ b/src/qt/qt_newfloppydialog.cpp @@ -49,8 +49,8 @@ struct disk_size_t { int encoding; int rpm; int tracks; - int sectors; /* For IMG and Japanese FDI only. */ - int sector_len; /* For IMG and Japanese FDI only. */ + int sectors; /* For IMG and Japanese FDI only. */ + int sector_len; /* For IMG and Japanese FDI only. */ int media_desc; int spc; int num_fats; @@ -58,20 +58,22 @@ struct disk_size_t { int root_dir_entries; }; -static const disk_size_t disk_sizes[14] = { { 0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */ - { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */ - { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112 }, /* 320k */ - { 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112 }, /* 360k */ - { 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112 }, /* 640k */ - { 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112 }, /* 720k */ - { 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224 }, /* 1.2M */ - { 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192 }, /* 1.25M */ - { 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224 }, /* 1.44M */ - { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ - { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ - { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240 }, /* 2.88M */ - { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ - { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } }; /* ZIP 250 */ +static const disk_size_t disk_sizes[14] = { + {0, 1, 2, 1, 0, 40, 8, 2, 0xfe, 2, 2, 1, 64 }, /* 160k */ + { 0, 1, 2, 1, 0, 40, 9, 2, 0xfc, 2, 2, 1, 64 }, /* 180k */ + { 0, 2, 2, 1, 0, 40, 8, 2, 0xff, 2, 2, 1, 112}, /* 320k */ + { 0, 2, 2, 1, 0, 40, 9, 2, 0xfd, 2, 2, 2, 112}, /* 360k */ + { 0, 2, 2, 1, 0, 80, 8, 2, 0xfb, 2, 2, 2, 112}, /* 640k */ + { 0, 2, 2, 1, 0, 80, 9, 2, 0xf9, 2, 2, 3, 112}, /* 720k */ + { 1, 2, 0, 1, 1, 80, 15, 2, 0xf9, 1, 2, 7, 224}, /* 1.2M */ + { 1, 2, 0, 1, 1, 77, 8, 3, 0xfe, 1, 2, 2, 192}, /* 1.25M */ + { 1, 2, 0, 1, 0, 80, 18, 2, 0xf0, 1, 2, 9, 224}, /* 1.44M */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 2, 2, 5, 16 }, /* DMF cluster 1024 */ + { 1, 2, 0, 1, 0, 80, 21, 2, 0xf0, 4, 2, 3, 16 }, /* DMF cluster 2048 */ + { 2, 2, 3, 1, 0, 80, 36, 2, 0xf0, 2, 2, 9, 240}, /* 2.88M */ + { 0, 64, 0, 0, 0, 96, 32, 2, 0, 0, 0, 0, 0 }, /* ZIP 100 */ + { 0, 64, 0, 0, 0, 239, 32, 2, 0, 0, 0, 0, 0 } +}; /* ZIP 250 */ static const QStringList rpmModes = { "Perfect RPM", @@ -113,41 +115,36 @@ static const QStringList moTypes = { "5.25\" 1.3 GB", }; -NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : - QDialog(parent), - ui(new Ui::NewFloppyDialog), - mediaType_(type) +NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) + : QDialog(parent) + , ui(new Ui::NewFloppyDialog) + , mediaType_(type) { ui->setupUi(this); ui->fileField->setCreateFile(true); - auto* model = ui->comboBoxSize->model(); + auto *model = ui->comboBoxSize->model(); switch (type) { - case MediaType::Floppy: - for (int i = 0; i < floppyTypes.size(); ++i) { - Models::AddEntry(model, tr(floppyTypes[i].toUtf8().data()), i); - } - ui->fileField->setFilter( - tr("All images") % - util::DlgFilter({ "86f","dsk","flp","im?","*fd?" }) % - tr("Basic sector images") % - util::DlgFilter({ "dsk","flp","im?","img","*fd?" }) % - tr("Surface images") % - util::DlgFilter({ "86f" }, true)); + case MediaType::Floppy: + for (int i = 0; i < floppyTypes.size(); ++i) { + Models::AddEntry(model, tr(floppyTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter( + tr("All images") % util::DlgFilter({ "86f", "dsk", "flp", "im?", "*fd?" }) % tr("Basic sector images") % util::DlgFilter({ "dsk", "flp", "im?", "img", "*fd?" }) % tr("Surface images") % util::DlgFilter({ "86f" }, true)); - break; - case MediaType::Zip: - for (int i = 0; i < zipTypes.size(); ++i) { - Models::AddEntry(model, tr(zipTypes[i].toUtf8().data()), i); - } - ui->fileField->setFilter(tr("ZIP images") % util::DlgFilter({ "im?","zdi" }, true)); - break; - case MediaType::Mo: - for (int i = 0; i < moTypes.size(); ++i) { - Models::AddEntry(model, tr(moTypes[i].toUtf8().data()), i); - } - ui->fileField->setFilter(tr("MO images") % util::DlgFilter({ "im?","mdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); - break; + break; + case MediaType::Zip: + for (int i = 0; i < zipTypes.size(); ++i) { + Models::AddEntry(model, tr(zipTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter(tr("ZIP images") % util::DlgFilter({ "im?", "zdi" }, true)); + break; + case MediaType::Mo: + for (int i = 0; i < moTypes.size(); ++i) { + Models::AddEntry(model, tr(moTypes[i].toUtf8().data()), i); + } + ui->fileField->setFilter(tr("MO images") % util::DlgFilter({ "im?", "mdi" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + break; } model = ui->comboBoxRpm->model(); @@ -155,7 +152,7 @@ NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : Models::AddEntry(model, tr(rpmModes[i].toUtf8().data()), i); } - connect(ui->fileField, &FileField::fileSelected, this, [this](const QString& filename) { + connect(ui->fileField, &FileField::fileSelected, this, [this](const QString &filename) { bool hide = true; if (mediaType_ == MediaType::Floppy) { if (QFileInfo(filename).suffix().toLower() == QStringLiteral("86f")) { @@ -172,134 +169,140 @@ NewFloppyDialog::NewFloppyDialog(MediaType type, QWidget *parent) : ui->comboBoxRpm->setHidden(true); } -NewFloppyDialog::~NewFloppyDialog() { +NewFloppyDialog::~NewFloppyDialog() +{ delete ui; } -QString NewFloppyDialog::fileName() const{ +QString +NewFloppyDialog::fileName() const +{ return ui->fileField->fileName(); } -void NewFloppyDialog::onCreate() { - auto filename = ui->fileField->fileName(); +void +NewFloppyDialog::onCreate() +{ + auto filename = ui->fileField->fileName(); QFileInfo fi(filename); - FileType fileType; + FileType fileType; QProgressDialog progress("Creating floppy image", QString(), 0, 100, this); connect(this, &NewFloppyDialog::fileProgress, &progress, &QProgressDialog::setValue); connect(this, &NewFloppyDialog::fileProgress, [] { QApplication::processEvents(); }); switch (mediaType_) { - case MediaType::Floppy: - if (fi.suffix().toLower() == QStringLiteral("86f")) { - if (create86f(filename, disk_sizes[ui->comboBoxSize->currentIndex()], ui->comboBoxRpm->currentIndex())) { - return; + case MediaType::Floppy: + if (fi.suffix().toLower() == QStringLiteral("86f")) { + if (create86f(filename, disk_sizes[ui->comboBoxSize->currentIndex()], ui->comboBoxRpm->currentIndex())) { + return; + } + } else { + fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Fdi : FileType::Img; + if (createSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex()], fileType)) { + return; + } } - } else { - fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Fdi : FileType::Img; - if (createSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex()], fileType)) { - return; + break; + case MediaType::Zip: + { + fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi : FileType::Img; + + std::atomic_bool res; + std::thread t([this, &res, filename, fileType, &progress] { + res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); + }); + progress.exec(); + t.join(); + + if (res) { + return; + } } - } - break; - case MediaType::Zip: - { - fileType = fi.suffix().toLower() == QStringLiteral("zdi") ? FileType::Zdi: FileType::Img; + break; + case MediaType::Mo: + { + fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi : FileType::Img; - std::atomic_bool res; - std::thread t([this, &res, filename, fileType, &progress] { - res = createZipSectorImage(filename, disk_sizes[ui->comboBoxSize->currentIndex() + 12], fileType, progress); - }); - progress.exec(); - t.join(); + std::atomic_bool res; + std::thread t([this, &res, filename, fileType, &progress] { + res = createMoSectorImage(filename, ui->comboBoxSize->currentIndex(), fileType, progress); + }); + progress.exec(); + t.join(); - if (res) { - return; - } - } - break; - case MediaType::Mo: - { - fileType = fi.suffix().toLower() == QStringLiteral("mdi") ? FileType::Mdi: FileType::Img; - - std::atomic_bool res; - std::thread t([this, &res, filename, fileType, &progress] { - res = createMoSectorImage(filename, ui->comboBoxSize->currentIndex(), fileType, progress); - }); - progress.exec(); - t.join(); - - if (res) { - return; - } - } - break; + if (res) { + return; + } + } + break; } QMessageBox::critical(this, tr("Unable to write file"), tr("Make sure the file is being saved to a writable directory")); reject(); } -bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode) +bool +NewFloppyDialog::create86f(const QString &filename, const disk_size_t &disk_size, uint8_t rpm_mode) { FILE *f; - uint32_t magic = 0x46423638; - uint16_t version = 0x020C; - uint16_t dflags = 0; - uint16_t tflags = 0; + uint32_t magic = 0x46423638; + uint16_t version = 0x020C; + uint16_t dflags = 0; + uint16_t tflags = 0; uint32_t index_hole_pos = 0; uint32_t tarray[512]; uint32_t array_size; uint32_t track_base, track_size; - int i; + int i; uint32_t shift = 0; - dflags = 0; /* Has surface data? - Assume no for now. */ - dflags |= (disk_size.hole << 1); /* Hole */ - dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ - dflags |= (0 << 4); /* Write protect? - Assume no for now. */ - dflags |= (rpm_mode << 5); /* RPM mode. */ - dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ + dflags = 0; /* Has surface data? - Assume no for now. */ + dflags |= (disk_size.hole << 1); /* Hole */ + dflags |= ((disk_size.sides - 1) << 3); /* Sides. */ + dflags |= (0 << 4); /* Write protect? - Assume no for now. */ + dflags |= (rpm_mode << 5); /* RPM mode. */ + dflags |= (0 << 7); /* Has extra bit cells? - Assume no for now. */ - tflags = disk_size.data_rate; /* Data rate. */ - tflags |= (disk_size.encoding << 3); /* Encoding. */ - tflags |= (disk_size.rpm << 5); /* RPM. */ + tflags = disk_size.data_rate; /* Data rate. */ + tflags |= (disk_size.encoding << 3); /* Encoding. */ + tflags |= (disk_size.rpm << 5); /* RPM. */ switch (disk_size.hole) { - case 0: - case 1: - default: - switch(rpm_mode) { - case 1: - array_size = 25250; - break; - case 2: - array_size = 25374; - break; - case 3: - array_size = 25750; - break; - default: - array_size = 25000; - break; - } - break; - case 2: - switch(rpm_mode) { - case 1: - array_size = 50500; - break; - case 2: - array_size = 50750; - break; - case 3: - array_size = 51000; - break; - default: - array_size = 50000; - break; - } - break; + case 0: + case 1: + default: + switch (rpm_mode) { + case 1: + array_size = 25250; + break; + case 2: + array_size = 25374; + break; + case 3: + array_size = 25750; + break; + default: + array_size = 25000; + break; + } + break; + case 2: + switch (rpm_mode) { + case 1: + array_size = 50500; + break; + case 2: + array_size = 50750; + break; + case 3: + array_size = 51000; + break; + default: + array_size = 50000; + break; + } + break; } auto empty = (unsigned char *) malloc(array_size); @@ -309,7 +312,7 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk f = plat_fopen(filename.toUtf8().data(), "wb"); if (!f) - return false; + return false; fwrite(&magic, 4, 1, f); fwrite(&version, 2, 1, f); @@ -320,17 +323,17 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk track_base = 8 + ((disk_size.sides == 2) ? 2048 : 1024); if (disk_size.tracks <= 43) - shift = 1; + shift = 1; for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) - tarray[i] = track_base + (i * track_size); + tarray[i] = track_base + (i * track_size); fwrite(tarray, 1, (disk_size.sides == 2) ? 2048 : 1024, f); for (i = 0; i < (disk_size.tracks * disk_size.sides) << shift; i++) { - fwrite(&tflags, 2, 1, f); - fwrite(&index_hole_pos, 4, 1, f); - fwrite(empty, 1, array_size, f); + fwrite(&tflags, 2, 1, f); + fwrite(&index_hole_pos, 4, 1, f); + fwrite(empty, 1, array_size, f); } free(empty); @@ -342,61 +345,62 @@ bool NewFloppyDialog::create86f(const QString& filename, const disk_size_t& disk /* Ignore false positive warning caused by a bug on gcc */ #if __GNUC__ >= 11 -#pragma GCC diagnostic ignored "-Wstringop-overflow" +# pragma GCC diagnostic ignored "-Wstringop-overflow" #endif -bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type) +bool +NewFloppyDialog::createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type) { - uint32_t total_size = 0; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; + uint32_t total_size = 0; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; uint32_t root_dir_bytes = 0; - uint32_t fat_size = 0; - uint32_t fat1_offs = 0; - uint32_t fat2_offs = 0; - uint32_t zero_bytes = 0; - uint16_t base = 0x1000; + uint32_t fat_size = 0; + uint32_t fat1_offs = 0; + uint32_t fat2_offs = 0; + uint32_t zero_bytes = 0; + uint16_t base = 0x1000; QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); - sector_bytes = (128 << disk_size.sector_len); + sector_bytes = (128 << disk_size.sector_len); total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; if (total_sectors > ZIP_SECTORS) total_sectors = ZIP_250_SECTORS; - total_size = total_sectors * sector_bytes; + total_size = total_sectors * sector_bytes; root_dir_bytes = (disk_size.root_dir_entries << 5); - fat_size = (disk_size.spfat * sector_bytes); - fat1_offs = sector_bytes; - fat2_offs = fat1_offs + fat_size; - zero_bytes = fat2_offs + fat_size + root_dir_bytes; + fat_size = (disk_size.spfat * sector_bytes); + fat1_offs = sector_bytes; + fat2_offs = fat1_offs + fat_size; + zero_bytes = fat2_offs + fat_size + root_dir_bytes; if (type == FileType::Fdi) { QByteArray bytes(base, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); *(uint32_t *) &(empty[0x08]) = (uint32_t) base; *(uint32_t *) &(empty[0x0C]) = total_size; *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; + *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; stream.writeRawData(empty, base); } QByteArray bytes(total_size, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); memset(empty + zero_bytes, 0xF6, total_size - zero_bytes); - empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ + empty[0x00] = 0xEB; /* Jump to make MS-DOS happy. */ empty[0x01] = 0x58; empty[0x02] = 0x90; - empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ + empty[0x03] = 0x38; /* '86BOX5.0' OEM ID. */ empty[0x04] = 0x36; empty[0x05] = 0x42; empty[0x06] = 0x4F; @@ -406,17 +410,17 @@ bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size empty[0x0A] = 0x30; *(uint16_t *) &(empty[0x0B]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; + *(uint8_t *) &(empty[0x0D]) = (uint8_t) disk_size.spc; *(uint16_t *) &(empty[0x0E]) = (uint16_t) 1; - *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; + *(uint8_t *) &(empty[0x10]) = (uint8_t) disk_size.num_fats; *(uint16_t *) &(empty[0x11]) = (uint16_t) disk_size.root_dir_entries; *(uint16_t *) &(empty[0x13]) = (uint16_t) total_sectors; - *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; + *(uint8_t *) &(empty[0x15]) = (uint8_t) disk_size.media_desc; *(uint16_t *) &(empty[0x16]) = (uint16_t) disk_size.spfat; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x1A]) = (uint8_t) disk_size.sides; - empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x26] = 0x29; /* ')' followed by randomly-generated volume serial number. */ empty[0x27] = random_generate(); empty[0x28] = random_generate(); empty[0x29] = random_generate(); @@ -442,22 +446,23 @@ bool NewFloppyDialog::createSectorImage(const QString &filename, const disk_size return true; } -bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar) +bool +NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar) { - uint32_t total_size = 0; + uint32_t total_size = 0; uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0; + uint32_t sector_bytes = 0; + uint16_t base = 0x1000; + uint32_t pbar_max = 0; QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); - sector_bytes = (128 << disk_size.sector_len); + sector_bytes = (128 << disk_size.sector_len); total_sectors = disk_size.sides * disk_size.tracks * disk_size.sectors; if (total_sectors > ZIP_SECTORS) total_sectors = ZIP_250_SECTORS; @@ -471,21 +476,21 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s if (type == FileType::Zdi) { QByteArray data(base, 0); - auto empty = data.data(); + auto empty = data.data(); *(uint32_t *) &(empty[0x08]) = (uint32_t) base; *(uint32_t *) &(empty[0x0C]) = total_size; *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; - *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; + *(uint8_t *) &(empty[0x14]) = (uint8_t) disk_size.sectors; + *(uint8_t *) &(empty[0x18]) = (uint8_t) disk_size.sides; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) disk_size.tracks; stream.writeRawData(empty, base); pbar_max -= 2; } QByteArray bytes(total_size, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); if (total_sectors == ZIP_SECTORS) { /* ZIP 100 */ @@ -515,7 +520,7 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s *(uint32_t *) &(empty[0x4020]) = 0x0002FFE0; *(uint16_t *) &(empty[0x4024]) = 0x0080; - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ empty[0x4027] = random_generate(); empty[0x4028] = random_generate(); empty[0x4029] = random_generate(); @@ -586,7 +591,7 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s *(uint32_t *) &(empty[0x4020]) = 0x000777E0; *(uint16_t *) &(empty[0x4024]) = 0x0080; - empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ + empty[0x4026] = 0x29; /* ')' followed by randomly-generated volume serial number. */ empty[0x4027] = random_generate(); empty[0x4028] = random_generate(); empty[0x4029] = random_generate(); @@ -624,26 +629,26 @@ bool NewFloppyDialog::createZipSectorImage(const QString &filename, const disk_s return true; } - -bool NewFloppyDialog::createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar) +bool +NewFloppyDialog::createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar) { - const mo_type_t *dp = &mo_types[disk_size]; - uint32_t total_size = 0, total_size2; - uint32_t total_sectors = 0; - uint32_t sector_bytes = 0; - uint16_t base = 0x1000; - uint32_t pbar_max = 0, blocks_num; + const mo_type_t *dp = &mo_types[disk_size]; + uint32_t total_size = 0, total_size2; + uint32_t total_sectors = 0; + uint32_t sector_bytes = 0; + uint16_t base = 0x1000; + uint32_t pbar_max = 0, blocks_num; QFile file(filename); - if (! file.open(QIODevice::WriteOnly)) { + if (!file.open(QIODevice::WriteOnly)) { return false; } QDataStream stream(&file); stream.setByteOrder(QDataStream::LittleEndian); - sector_bytes = dp->bytes_per_sector; + sector_bytes = dp->bytes_per_sector; total_sectors = dp->sectors; - total_size = total_sectors * sector_bytes; + total_size = total_sectors * sector_bytes; total_size2 = (total_size >> 20) << 20; total_size2 = total_size - total_size2; @@ -658,20 +663,20 @@ bool NewFloppyDialog::createMoSectorImage(const QString& filename, int8_t disk_s if (type == FileType::Mdi) { QByteArray bytes(base, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); *(uint32_t *) &(empty[0x08]) = (uint32_t) base; *(uint32_t *) &(empty[0x0C]) = total_size; *(uint16_t *) &(empty[0x10]) = (uint16_t) sector_bytes; - *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; - *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; - *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; + *(uint8_t *) &(empty[0x14]) = (uint8_t) 25; + *(uint8_t *) &(empty[0x18]) = (uint8_t) 64; + *(uint8_t *) &(empty[0x1C]) = (uint8_t) (dp->sectors / 64) / 25; stream.writeRawData(empty, base); } QByteArray bytes(1048576, 0); - auto empty = bytes.data(); + auto empty = bytes.data(); pbar.setMaximum(blocks_num); for (uint32_t i = 0; i < blocks_num; i++) { diff --git a/src/qt/qt_newfloppydialog.hpp b/src/qt/qt_newfloppydialog.hpp index 12e761cdf..a342df567 100644 --- a/src/qt/qt_newfloppydialog.hpp +++ b/src/qt/qt_newfloppydialog.hpp @@ -10,8 +10,7 @@ class NewFloppyDialog; struct disk_size_t; class QProgressDialog; -class NewFloppyDialog : public QDialog -{ +class NewFloppyDialog : public QDialog { Q_OBJECT public: @@ -39,12 +38,12 @@ private slots: private: Ui::NewFloppyDialog *ui; - MediaType mediaType_; + MediaType mediaType_; - bool create86f(const QString& filename, const disk_size_t& disk_size, uint8_t rpm_mode); - bool createSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type); - bool createZipSectorImage(const QString& filename, const disk_size_t& disk_size, FileType type, QProgressDialog& pbar); - bool createMoSectorImage(const QString& filename, int8_t disk_size, FileType type, QProgressDialog& pbar); + bool create86f(const QString &filename, const disk_size_t &disk_size, uint8_t rpm_mode); + bool createSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type); + bool createZipSectorImage(const QString &filename, const disk_size_t &disk_size, FileType type, QProgressDialog &pbar); + bool createMoSectorImage(const QString &filename, int8_t disk_size, FileType type, QProgressDialog &pbar); }; #endif // QT_NEWFLOPPYDIALOG_HPP diff --git a/src/qt/qt_openglrenderer.cpp b/src/qt/qt_openglrenderer.cpp index 6d5b36d80..a2f1ecad0 100644 --- a/src/qt/qt_openglrenderer.cpp +++ b/src/qt/qt_openglrenderer.cpp @@ -27,11 +27,11 @@ #include "qt_openglrenderer.hpp" #ifndef GL_MAP_PERSISTENT_BIT -#define GL_MAP_PERSISTENT_BIT 0x0040 +# define GL_MAP_PERSISTENT_BIT 0x0040 #endif #ifndef GL_MAP_COHERENT_BIT -#define GL_MAP_COHERENT_BIT 0x0080 +# define GL_MAP_COHERENT_BIT 0x0080 #endif OpenGLRenderer::OpenGLRenderer(QWidget *parent) @@ -321,7 +321,10 @@ OpenGLRenderer::applyOptions() void OpenGLRenderer::reloadOptions() { - if (options) { delete options; options = nullptr; } + if (options) { + delete options; + options = nullptr; + } options = new OpenGLOptions(this, true, glslVersion); applyOptions(); diff --git a/src/qt/qt_openglrenderer.hpp b/src/qt/qt_openglrenderer.hpp index 99393c30d..c303ca614 100644 --- a/src/qt/qt_openglrenderer.hpp +++ b/src/qt/qt_openglrenderer.hpp @@ -39,7 +39,7 @@ #include "qt_opengloptions.hpp" #include "qt_renderercommon.hpp" -typedef void (QOPENGLF_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC_LOCAL) (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); +typedef void(QOPENGLF_APIENTRYP PFNGLBUFFERSTORAGEEXTPROC_LOCAL)(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); class OpenGLRenderer : public QWindow, protected QOpenGLExtraFunctions, public RendererCommon { Q_OBJECT diff --git a/src/qt/qt_platform.cpp b/src/qt/qt_platform.cpp index df80b8912..812fe97b3 100644 --- a/src/qt/qt_platform.cpp +++ b/src/qt/qt_platform.cpp @@ -44,23 +44,28 @@ #include "qt_progsettings.hpp" #ifdef Q_OS_UNIX -#include +# include #endif // static QByteArray buf; extern QElapsedTimer elapsed_timer; -extern MainWindow* main_window; -QElapsedTimer elapsed_timer; +extern MainWindow *main_window; +QElapsedTimer elapsed_timer; -static std::atomic_int blitmx_contention = 0; +static std::atomic_int blitmx_contention = 0; static std::recursive_mutex blitmx; class CharPointer { public: - CharPointer(char* buf, int size) : b(buf), s(size) {} - CharPointer& operator=(const QByteArray &ba) { + CharPointer(char *buf, int size) + : b(buf) + , s(size) + { + } + CharPointer &operator=(const QByteArray &ba) + { if (s > 0) { - strncpy(b, ba.data(), s-1); + strncpy(b, ba.data(), s - 1); b[s] = 0; } else { // if we haven't been told the length of b, just assume enough @@ -70,9 +75,10 @@ public: } return *this; } + private: - char* b; - int s; + char *b; + int s; }; extern "C" { @@ -101,18 +107,19 @@ extern "C" { #include "../cpu/cpu.h" #include <86box/plat.h> -volatile int cpu_thread_run = 1; -int mouse_capture = 0; -int fixed_size_x = 640; -int fixed_size_y = 480; -int rctrl_is_lalt = 0; -int update_icons = 1; -int kbd_req_capture = 0; -int hide_status_bar = 0; -int hide_tool_bar = 0; -uint32_t lang_id = 0x0409, lang_sys = 0x0409; // Multilangual UI variables, for now all set to LCID of en-US +volatile int cpu_thread_run = 1; +int mouse_capture = 0; +int fixed_size_x = 640; +int fixed_size_y = 480; +int rctrl_is_lalt = 0; +int update_icons = 1; +int kbd_req_capture = 0; +int hide_status_bar = 0; +int hide_tool_bar = 0; +uint32_t lang_id = 0x0409, lang_sys = 0x0409; // Multilangual UI variables, for now all set to LCID of en-US -int stricmp(const char* s1, const char* s2) +int +stricmp(const char *s1, const char *s2) { #ifdef Q_OS_WINDOWS return _stricmp(s1, s2); @@ -121,7 +128,8 @@ int stricmp(const char* s1, const char* s2) #endif } -int strnicmp(const char *s1, const char *s2, size_t n) +int +strnicmp(const char *s1, const char *s2, size_t n) { #ifdef Q_OS_WINDOWS return _strnicmp(s1, s2, n); @@ -134,14 +142,15 @@ void do_stop(void) { cpu_thread_run = 0; - //main_window->close(); + // main_window->close(); } -void plat_get_exe_name(char *s, int size) +void +plat_get_exe_name(char *s, int size) { QByteArray exepath_temp = QCoreApplication::applicationDirPath().toLocal8Bit(); - memcpy(s, exepath_temp.data(), std::min((qsizetype)exepath_temp.size(),(qsizetype)size)); + memcpy(s, exepath_temp.data(), std::min((qsizetype) exepath_temp.size(), (qsizetype) size)); path_slash(s); } @@ -163,7 +172,7 @@ plat_fopen(const char *path, const char *mode) { #if defined(Q_OS_MACOS) or defined(Q_OS_LINUX) QFileInfo fi(path); - QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); + QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); return fopen(filename.toUtf8().constData(), mode); #else return fopen(QString::fromUtf8(path).toLocal8Bit(), mode); @@ -175,7 +184,7 @@ plat_fopen64(const char *path, const char *mode) { #if defined(Q_OS_MACOS) or defined(Q_OS_LINUX) QFileInfo fi(path); - QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); + QString filename = (fi.isRelative() && !fi.filePath().isEmpty()) ? usr_path + fi.filePath() : fi.filePath(); return fopen(filename.toUtf8().constData(), mode); #else return fopen(QString::fromUtf8(path).toLocal8Bit(), mode); @@ -220,9 +229,9 @@ path_get_extension(char *s) auto len = strlen(s); auto idx = QByteArray::fromRawData(s, len).lastIndexOf('.'); if (idx >= 0) { - return s+idx+1; + return s + idx + 1; } - return s+len; + return s + len; } char * @@ -232,16 +241,16 @@ path_get_filename(char *s) int c = strlen(s) - 1; while (c > 0) { - if (s[c] == '/' || s[c] == '\\') - return(&s[c+1]); - c--; + if (s[c] == '/' || s[c] == '\\') + return (&s[c + 1]); + c--; } - return(s); + return (s); #else - auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); + auto idx = QByteArray::fromRawData(s, strlen(s)).lastIndexOf(QDir::separator().toLatin1()); if (idx >= 0) { - return s+idx+1; + return s + idx + 1; } return s; #endif @@ -261,12 +270,12 @@ path_abs(char *path) } void -path_normalize(char* path) +path_normalize(char *path) { #ifdef Q_OS_WINDOWS - while (*path++ != 0) - { - if (*path == '\\') *path = '/'; + while (*path++ != 0) { + if (*path == '\\') + *path = '/'; } #endif } @@ -274,11 +283,11 @@ path_normalize(char* path) void path_slash(char *path) { - auto len = strlen(path); + auto len = strlen(path); auto separator = '/'; - if (path[len-1] != separator) { - path[len] = separator; - path[len+1] = 0; + if (path[len - 1] != separator) { + path[len] = separator; + path[len + 1] = 0; } path_normalize(path); } @@ -300,12 +309,14 @@ plat_tempfile(char *bufp, char *prefix, char *suffix) name.append(QString("%1-").arg(prefix)); } - name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzzz")); - if (suffix) name.append(suffix); - strcpy(bufp, name.toUtf8().data()); + name.append(QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss-zzzz")); + if (suffix) + name.append(suffix); + strcpy(bufp, name.toUtf8().data()); } -void plat_remove(char* path) +void +plat_remove(char *path) { QFile(path).remove(); } @@ -316,11 +327,11 @@ plat_mmap(size_t size, uint8_t executable) #if defined Q_OS_WINDOWS return VirtualAlloc(NULL, size, MEM_COMMIT, executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); #elif defined Q_OS_UNIX -#if defined Q_OS_DARWIN && defined MAP_JIT +# if defined Q_OS_DARWIN && defined MAP_JIT void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE | (executable ? MAP_JIT : 0), -1, 0); -#else +# else void *ret = mmap(0, size, PROT_READ | PROT_WRITE | (executable ? PROT_EXEC : 0), MAP_ANON | MAP_PRIVATE, -1, 0); -#endif +# endif return (ret == MAP_FAILED) ? nullptr : ret; #endif } @@ -339,12 +350,12 @@ void plat_pause(int p) { static wchar_t oldtitle[512]; - wchar_t title[1024], paused_msg[512]; + wchar_t title[1024], paused_msg[512]; if (p == dopause) { #ifdef Q_OS_WINDOWS if (source_hwnd) - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDSTATUS, (WPARAM)!!p, (LPARAM)(HWND)main_window->winId()); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); #endif return; } @@ -354,8 +365,8 @@ plat_pause(int p) dopause = p; if (p) { - if (mouse_capture) - plat_mouse_capture(0); + if (mouse_capture) + plat_mouse_capture(0); wcsncpy(oldtitle, ui_window_title(NULL), sizeof_w(oldtitle) - 1); wcscpy(title, oldtitle); @@ -370,12 +381,12 @@ plat_pause(int p) #ifdef Q_OS_WINDOWS if (source_hwnd) - PostMessage((HWND)(uintptr_t)source_hwnd, WM_SENDSTATUS, (WPARAM)!!p, (LPARAM)(HWND)main_window->winId()); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!p, (LPARAM) (HWND) main_window->winId()); #endif } // because we can't include nvr.h because it's got fields named new -extern int nvr_save(void); +extern int nvr_save(void); void plat_power_off(void) @@ -393,45 +404,45 @@ plat_power_off(void) QTimer::singleShot(0, (const QWidget *) main_window, &QMainWindow::close); } -void set_language(uint32_t id) { +void +set_language(uint32_t id) +{ lang_id = id; } -extern "C++" -{ - QMap> ProgSettings::lcid_langcode = - { - {0x0405, {"cs-CZ", "Czech (Czech Republic)"} }, - {0x0407, {"de-DE", "German (Germany)"} }, - {0x0409, {"en-US", "English (United States)"} }, - {0x0809, {"en-GB", "English (United Kingdom)"} }, - {0x0C0A, {"es-ES", "Spanish (Spain)"} }, - {0x040B, {"fi-FI", "Finnish (Finland)"} }, - {0x040C, {"fr-FR", "French (France)"} }, - {0x041A, {"hr-HR", "Croatian (Croatia)"} }, - {0x040E, {"hu-HU", "Hungarian (Hungary)"} }, - {0x0410, {"it-IT", "Italian (Italy)"} }, - {0x0411, {"ja-JP", "Japanese (Japan)"} }, - {0x0412, {"ko-KR", "Korean (Korea)"} }, - {0x0415, {"pl-PL", "Polish (Poland)"} }, - {0x0416, {"pt-BR", "Portuguese (Brazil)"} }, - {0x0816, {"pt-PT", "Portuguese (Portugal)"} }, - {0x0419, {"ru-RU", "Russian (Russia)"} }, - {0x0424, {"sl-SI", "Slovenian (Slovenia)"} }, - {0x041F, {"tr-TR", "Turkish (Turkey)"} }, - {0x0422, {"uk-UA", "Ukrainian (Ukraine)"} }, - {0x0804, {"zh-CN", "Chinese (China)"} }, - {0x0404, {"zh-TW", "Chinese (Taiwan)"} }, - {0xFFFF, {"system", "(System Default)"} }, - }; +extern "C++" { +QMap> ProgSettings::lcid_langcode = { + {0x0405, { "cs-CZ", "Czech (Czech Republic)" } }, + { 0x0407, { "de-DE", "German (Germany)" } }, + { 0x0409, { "en-US", "English (United States)" } }, + { 0x0809, { "en-GB", "English (United Kingdom)" }}, + { 0x0C0A, { "es-ES", "Spanish (Spain)" } }, + { 0x040B, { "fi-FI", "Finnish (Finland)" } }, + { 0x040C, { "fr-FR", "French (France)" } }, + { 0x041A, { "hr-HR", "Croatian (Croatia)" } }, + { 0x040E, { "hu-HU", "Hungarian (Hungary)" } }, + { 0x0410, { "it-IT", "Italian (Italy)" } }, + { 0x0411, { "ja-JP", "Japanese (Japan)" } }, + { 0x0412, { "ko-KR", "Korean (Korea)" } }, + { 0x0415, { "pl-PL", "Polish (Poland)" } }, + { 0x0416, { "pt-BR", "Portuguese (Brazil)" } }, + { 0x0816, { "pt-PT", "Portuguese (Portugal)" } }, + { 0x0419, { "ru-RU", "Russian (Russia)" } }, + { 0x0424, { "sl-SI", "Slovenian (Slovenia)" } }, + { 0x041F, { "tr-TR", "Turkish (Turkey)" } }, + { 0x0422, { "uk-UA", "Ukrainian (Ukraine)" } }, + { 0x0804, { "zh-CN", "Chinese (China)" } }, + { 0x0404, { "zh-TW", "Chinese (Taiwan)" } }, + { 0xFFFF, { "system", "(System Default)" } }, +}; } /* Sets up the program language before initialization. */ -uint32_t plat_language_code(char* langcode) { - for (auto& curKey : ProgSettings::lcid_langcode.keys()) - { - if (ProgSettings::lcid_langcode[curKey].first == langcode) - { +uint32_t +plat_language_code(char *langcode) +{ + for (auto &curKey : ProgSettings::lcid_langcode.keys()) { + if (ProgSettings::lcid_langcode[curKey].first == langcode) { return curKey; } } @@ -439,9 +450,10 @@ uint32_t plat_language_code(char* langcode) { } /* Converts back the language code to LCID */ -void plat_language_code_r(uint32_t lcid, char* outbuf, int len) { - if (!ProgSettings::lcid_langcode.contains(lcid)) - { +void +plat_language_code_r(uint32_t lcid, char *outbuf, int len) +{ + if (!ProgSettings::lcid_langcode.contains(lcid)) { qstrncpy(outbuf, "system", len); return; } @@ -450,25 +462,25 @@ void plat_language_code_r(uint32_t lcid, char* outbuf, int len) { } #ifndef Q_OS_WINDOWS -void* dynld_module(const char *name, dllimp_t *table) +void * +dynld_module(const char *name, dllimp_t *table) { - QString libraryName = name; - QFileInfo fi(libraryName); - QStringList removeSuffixes = {"dll", "dylib", "so"}; + QString libraryName = name; + QFileInfo fi(libraryName); + QStringList removeSuffixes = { "dll", "dylib", "so" }; if (removeSuffixes.contains(fi.suffix())) { libraryName = fi.completeBaseName(); } auto lib = std::unique_ptr(new QLibrary(libraryName)); if (lib->load()) { - for (auto imp = table; imp->name != nullptr; imp++) - { + for (auto imp = table; imp->name != nullptr; imp++) { auto ptr = lib->resolve(imp->name); if (ptr == nullptr) { return nullptr; } - auto imp_ptr = reinterpret_cast(imp->func); - *imp_ptr = reinterpret_cast(ptr); + auto imp_ptr = reinterpret_cast(imp->func); + *imp_ptr = reinterpret_cast(ptr); } } else { return nullptr; @@ -477,13 +489,15 @@ void* dynld_module(const char *name, dllimp_t *table) return lib.release(); } -void dynld_close(void *handle) +void +dynld_close(void *handle) { - delete reinterpret_cast(handle); + delete reinterpret_cast(handle); } #endif -void startblit() +void +startblit() { blitmx_contention++; if (blitmx.try_lock()) { @@ -493,7 +507,8 @@ void startblit() blitmx.lock(); } -void endblit() +void +endblit() { blitmx_contention--; blitmx.unlock(); @@ -504,33 +519,38 @@ void endblit() std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } - } #ifdef Q_OS_WINDOWS -size_t mbstoc16s(uint16_t dst[], const char src[], int len) +size_t +mbstoc16s(uint16_t dst[], const char src[], int len) { - if (src == NULL) return 0; - if (len < 0) return 0; + if (src == NULL) + return 0; + if (len < 0) + return 0; size_t ret = MultiByteToWideChar(CP_UTF8, 0, src, -1, reinterpret_cast(dst), dst == NULL ? 0 : len); if (!ret) { - return -1; + return -1; } return ret; } -size_t c16stombs(char dst[], const uint16_t src[], int len) +size_t +c16stombs(char dst[], const uint16_t src[], int len) { - if (src == NULL) return 0; - if (len < 0) return 0; + if (src == NULL) + return 0; + if (len < 0) + return 0; size_t ret = WideCharToMultiByte(CP_UTF8, 0, reinterpret_cast(src), -1, dst, dst == NULL ? 0 : len, NULL, NULL); if (!ret) { - return -1; + return -1; } return ret; @@ -538,21 +558,21 @@ size_t c16stombs(char dst[], const uint16_t src[], int len) #endif #ifdef _WIN32 -#define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" -#define LIB_NAME_GS "gsdll32.dll" -#define LIB_NAME_FREETYPE "freetype.dll" -#define MOUSE_CAPTURE_KEYSEQ "F8+F12" +# define LIB_NAME_FLUIDSYNTH "libfluidsynth.dll" +# define LIB_NAME_GS "gsdll32.dll" +# define LIB_NAME_FREETYPE "freetype.dll" +# define MOUSE_CAPTURE_KEYSEQ "F8+F12" #else -#define LIB_NAME_FLUIDSYNTH "libfluidsynth" -#define LIB_NAME_GS "libgs" -#define LIB_NAME_FREETYPE "libfreetype" -#define MOUSE_CAPTURE_KEYSEQ "CTRL-END" +# define LIB_NAME_FLUIDSYNTH "libfluidsynth" +# define LIB_NAME_GS "libgs" +# define LIB_NAME_FREETYPE "libfreetype" +# define MOUSE_CAPTURE_KEYSEQ "CTRL-END" #endif - QMap ProgSettings::translatedstrings; -void ProgSettings::reloadStrings() +void +ProgSettings::reloadStrings() { translatedstrings.clear(); translatedstrings[IDS_2077] = QCoreApplication::translate("", "Click to capture mouse").toStdWString(); @@ -576,31 +596,30 @@ void ProgSettings::reloadStrings() translatedstrings[IDS_2056] = QCoreApplication::translate("", "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory.").toStdWString(); auto flsynthstr = QCoreApplication::translate("", " is required for FluidSynth MIDI output."); - if (flsynthstr.contains("libfluidsynth")) - { + if (flsynthstr.contains("libfluidsynth")) { flsynthstr.replace("libfluidsynth", LIB_NAME_FLUIDSYNTH); - } - else flsynthstr.prepend(LIB_NAME_FLUIDSYNTH); + } else + flsynthstr.prepend(LIB_NAME_FLUIDSYNTH); translatedstrings[IDS_2134] = flsynthstr.toStdWString(); - auto gssynthstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); - if (gssynthstr.contains("libgs")) - { + auto gssynthstr = QCoreApplication::translate("", " is required for automatic conversion of PostScript files to PDF.\n\nAny documents sent to the generic PostScript printer will be saved as PostScript (.ps) files."); + if (gssynthstr.contains("libgs")) { gssynthstr.replace("libgs", LIB_NAME_GS); - } - else gssynthstr.prepend(LIB_NAME_GS); + } else + gssynthstr.prepend(LIB_NAME_GS); translatedstrings[IDS_2133] = gssynthstr.toStdWString(); - auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation."); - if (ftsynthstr.contains("libfreetype")) - { + auto ftsynthstr = QCoreApplication::translate("", " is required for ESC/P printer emulation."); + if (ftsynthstr.contains("libfreetype")) { ftsynthstr.replace("libfreetype", LIB_NAME_FREETYPE); - } - else ftsynthstr.prepend(LIB_NAME_FREETYPE); + } else + ftsynthstr.prepend(LIB_NAME_FREETYPE); translatedstrings[IDS_2132] = ftsynthstr.toStdWString(); } -wchar_t* plat_get_string(int i) +wchar_t * +plat_get_string(int i) { - if (ProgSettings::translatedstrings.empty()) ProgSettings::reloadStrings(); + if (ProgSettings::translatedstrings.empty()) + ProgSettings::reloadStrings(); return ProgSettings::translatedstrings[i].data(); } @@ -624,7 +643,7 @@ plat_init_rom_paths() paths.removeLast(); #endif - for (auto& path : paths) { + for (auto &path : paths) { #ifdef __APPLE__ rom_add_path(QDir(path).filePath("net.86Box.86Box/roms").toUtf8().constData()); #else diff --git a/src/qt/qt_progsettings.cpp b/src/qt/qt_progsettings.cpp index 6018b0158..3ee998002 100644 --- a/src/qt/qt_progsettings.cpp +++ b/src/qt/qt_progsettings.cpp @@ -27,8 +27,7 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/version.h> #include <86box/config.h> @@ -37,13 +36,13 @@ extern "C" #include <86box/rom.h> } - static QMap iconset_to_qt; -extern MainWindow* main_window; +extern MainWindow *main_window; -ProgSettings::CustomTranslator* ProgSettings::translator = nullptr; -QTranslator* ProgSettings::qtTranslator = nullptr; -QString ProgSettings::getIconSetPath() +ProgSettings::CustomTranslator *ProgSettings::translator = nullptr; +QTranslator *ProgSettings::qtTranslator = nullptr; +QString +ProgSettings::getIconSetPath() { if (iconset_to_qt.isEmpty()) { // Always include default bundled icons @@ -66,46 +65,48 @@ QString ProgSettings::getIconSetPath() return iconset_to_qt[icon_set]; } -QIcon ProgSettings::loadIcon(QString file) +QIcon +ProgSettings::loadIcon(QString file) { - (void)getIconSetPath(); - if (!QFile::exists(iconset_to_qt[icon_set] + file)) return QIcon(iconset_to_qt[""] + file); + (void) getIconSetPath(); + if (!QFile::exists(iconset_to_qt[icon_set] + file)) + return QIcon(iconset_to_qt[""] + file); return QIcon(iconset_to_qt[icon_set] + file); } -ProgSettings::ProgSettings(QWidget *parent) : - QDialog(parent), - ui(new Ui::ProgSettings) +ProgSettings::ProgSettings(QWidget *parent) + : QDialog(parent) + , ui(new Ui::ProgSettings) { ui->setupUi(this); - (void)getIconSetPath(); + (void) getIconSetPath(); ui->comboBox->setItemData(0, ""); ui->comboBox->setCurrentIndex(0); - for (auto i = iconset_to_qt.begin(); i != iconset_to_qt.end(); i++) - { - if (i.key() == "") continue; + for (auto i = iconset_to_qt.begin(); i != iconset_to_qt.end(); i++) { + if (i.key() == "") + continue; QFile iconfile(i.value() + "/iconinfo.txt"); iconfile.open(QFile::ReadOnly); QString friendlyName; QString iconsetinfo(iconfile.readAll()); iconfile.close(); - if (iconsetinfo.isEmpty()) friendlyName = i.key(); - else friendlyName = iconsetinfo.split('\n')[0]; + if (iconsetinfo.isEmpty()) + friendlyName = i.key(); + else + friendlyName = iconsetinfo.split('\n')[0]; ui->comboBox->addItem(friendlyName, i.key()); - if (strcmp(icon_set, i.key().toUtf8().data()) == 0) - { + if (strcmp(icon_set, i.key().toUtf8().data()) == 0) { ui->comboBox->setCurrentIndex(ui->comboBox->findData(i.key())); } } ui->comboBox->setItemData(0, '(' + tr("Default") + ')', Qt::DisplayRole); ui->comboBoxLanguage->setItemData(0, 0xFFFF); - for (auto i = lcid_langcode.begin(); i != lcid_langcode.end(); i++) - { - if (i.key() == 0xFFFF) continue; + for (auto i = lcid_langcode.begin(); i != lcid_langcode.end(); i++) { + if (i.key() == 0xFFFF) + continue; ui->comboBoxLanguage->addItem(lcid_langcode[i.key()].second, i.key()); - if (i.key() == lang_id) - { + if (i.key() == lang_id) { ui->comboBoxLanguage->setCurrentIndex(ui->comboBoxLanguage->findData(i.key())); } } @@ -115,10 +116,11 @@ ProgSettings::ProgSettings(QWidget *parent) : ui->openDirUsrPath->setChecked(open_dir_usr_path > 0); } -void ProgSettings::accept() +void +ProgSettings::accept() { strcpy(icon_set, ui->comboBox->currentData().toString().toUtf8().data()); - lang_id = ui->comboBoxLanguage->currentData().toUInt(); + lang_id = ui->comboBoxLanguage->currentData().toUInt(); open_dir_usr_path = ui->openDirUsrPath->isChecked() ? 1 : 0; loadTranslators(QCoreApplication::instance()); @@ -126,7 +128,8 @@ void ProgSettings::accept() update_mouse_msg(); main_window->ui->retranslateUi(main_window); QString vmname(vm_name); - if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') vmname.truncate(vmname.size() - 1); + if (vmname.at(vmname.size() - 1) == '"' || vmname.at(vmname.size() - 1) == '\'') + vmname.truncate(vmname.size() - 1); main_window->setWindowTitle(QString("%1 - %2 %3").arg(vmname, EMU_NAME, EMU_VERSION_FULL)); QString msg = main_window->status->getMessage(); main_window->status.reset(new MachineStatus(main_window)); @@ -143,47 +146,42 @@ ProgSettings::~ProgSettings() delete ui; } -void ProgSettings::on_pushButton_released() +void +ProgSettings::on_pushButton_released() { ui->comboBox->setCurrentIndex(0); } -void ProgSettings::loadTranslators(QObject *parent) +void +ProgSettings::loadTranslators(QObject *parent) { - if (qtTranslator) - { + if (qtTranslator) { QApplication::removeTranslator(qtTranslator); qtTranslator = nullptr; } - if (translator) - { + if (translator) { QApplication::removeTranslator(translator); translator = nullptr; } - qtTranslator = new QTranslator(parent); - translator = new CustomTranslator(parent); + qtTranslator = new QTranslator(parent); + translator = new CustomTranslator(parent); QString localetofilename = ""; - if (lang_id == 0xFFFF || lcid_langcode.contains(lang_id) == false) - { - for (int i = 0; i < QLocale::system().uiLanguages().size(); i++) - { + if (lang_id == 0xFFFF || lcid_langcode.contains(lang_id) == false) { + for (int i = 0; i < QLocale::system().uiLanguages().size(); i++) { localetofilename = QLocale::system().uiLanguages()[i]; - if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/"))) - { + if (translator->load(QLatin1String("86box_") + localetofilename, QLatin1String(":/"))) { qDebug() << "Translations loaded.\n"; QCoreApplication::installTranslator(translator); if (!qtTranslator->load(QLatin1String("qtbase_") + localetofilename.replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) qtTranslator->load(QLatin1String("qt_") + localetofilename.replace('-', '_'), QApplication::applicationDirPath() + "/./translations/"); - if (QApplication::installTranslator(qtTranslator)) - { - qDebug() << "Qt translations loaded." << "\n"; + if (QApplication::installTranslator(qtTranslator)) { + qDebug() << "Qt translations loaded." + << "\n"; } break; } } - } - else - { + } else { translator->load(QLatin1String("86box_") + lcid_langcode[lang_id].first, QLatin1String(":/")); QCoreApplication::installTranslator(translator); if (!qtTranslator->load(QLatin1String("qtbase_") + QString(lcid_langcode[lang_id].first).replace('-', '_'), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) @@ -192,20 +190,21 @@ void ProgSettings::loadTranslators(QObject *parent) } } -void ProgSettings::on_pushButtonLanguage_released() +void +ProgSettings::on_pushButtonLanguage_released() { ui->comboBoxLanguage->setCurrentIndex(0); } -void ProgSettings::on_horizontalSlider_valueChanged(int value) +void +ProgSettings::on_horizontalSlider_valueChanged(int value) { - mouseSensitivity = (double)value / 100.; + mouseSensitivity = (double) value / 100.; } - -void ProgSettings::on_pushButton_2_clicked() +void +ProgSettings::on_pushButton_2_clicked() { mouseSensitivity = 1.0; ui->horizontalSlider->setValue(100); } - diff --git a/src/qt/qt_progsettings.hpp b/src/qt/qt_progsettings.hpp index 07cf62051..7565869b0 100644 --- a/src/qt/qt_progsettings.hpp +++ b/src/qt/qt_progsettings.hpp @@ -8,32 +8,36 @@ namespace Ui { class ProgSettings; } -class ProgSettings : public QDialog -{ +class ProgSettings : public QDialog { Q_OBJECT public: explicit ProgSettings(QWidget *parent = nullptr); ~ProgSettings(); static QString getIconSetPath(); - static QIcon loadIcon(QString file); - static void loadTranslators(QObject* parent = nullptr); - static void reloadStrings(); - class CustomTranslator : public QTranslator - { + static QIcon loadIcon(QString file); + static void loadTranslators(QObject *parent = nullptr); + static void reloadStrings(); + class CustomTranslator : public QTranslator { public: - CustomTranslator(QObject* parent = nullptr) : QTranslator(parent) {}; + CustomTranslator(QObject *parent = nullptr) + : QTranslator(parent) {}; + protected: QString translate(const char *context, const char *sourceText, - const char *disambiguation = nullptr, int n = -1) const override + const char *disambiguation = nullptr, int n = -1) const override { - if (strcmp(sourceText, "&Fullscreen") == 0) sourceText = "&Fullscreen\tCtrl+Alt+PgUp"; - if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) sourceText = "&Ctrl+Alt+Del\tCtrl+F12"; - if (strcmp(sourceText, "Take s&creenshot") == 0) sourceText = "Take s&creenshot\tCtrl+F11"; - if (strcmp(sourceText, "Begin trace") == 0) sourceText = "Begin trace\tCtrl+T"; - if (strcmp(sourceText, "End trace") == 0) sourceText = "End trace\tCtrl+T"; - if (strcmp(sourceText, "&Qt (Software)") == 0) - { + if (strcmp(sourceText, "&Fullscreen") == 0) + sourceText = "&Fullscreen\tCtrl+Alt+PgUp"; + if (strcmp(sourceText, "&Ctrl+Alt+Del") == 0) + sourceText = "&Ctrl+Alt+Del\tCtrl+F12"; + if (strcmp(sourceText, "Take s&creenshot") == 0) + sourceText = "Take s&creenshot\tCtrl+F11"; + if (strcmp(sourceText, "Begin trace") == 0) + sourceText = "Begin trace\tCtrl+T"; + if (strcmp(sourceText, "End trace") == 0) + sourceText = "End trace\tCtrl+T"; + if (strcmp(sourceText, "&Qt (Software)") == 0) { QString finalstr = QTranslator::translate("", "&SDL (Software)", disambiguation, n); finalstr.replace("SDL", "Qt"); finalstr.replace("(&S)", "(&Q)"); @@ -41,15 +45,16 @@ public: } QString finalstr = QTranslator::translate("", sourceText, disambiguation, n); #ifdef Q_OS_MACOS - if (finalstr.contains('\t')) finalstr.truncate(finalstr.indexOf('\t')); + if (finalstr.contains('\t')) + finalstr.truncate(finalstr.indexOf('\t')); #endif return finalstr; } }; - static CustomTranslator* translator; - static QTranslator* qtTranslator; + static CustomTranslator *translator; + static QTranslator *qtTranslator; static QMap> lcid_langcode; - static QMap translatedstrings; + static QMap translatedstrings; protected slots: void accept() override; diff --git a/src/qt/qt_renderercommon.cpp b/src/qt/qt_renderercommon.cpp index 0b8108b00..98fb27ca0 100644 --- a/src/qt/qt_renderercommon.cpp +++ b/src/qt/qt_renderercommon.cpp @@ -32,79 +32,83 @@ extern "C" { RendererCommon::RendererCommon() = default; -extern MainWindow* main_window; +extern MainWindow *main_window; -static void integer_scale(double *d, double *g) { +static void +integer_scale(double *d, double *g) +{ double ratio; if (*d > *g) { ratio = std::floor(*d / *g); - *d = *g * ratio; + *d = *g * ratio; } else { ratio = std::ceil(*d / *g); - *d = *g / ratio; + *d = *g / ratio; } } -void RendererCommon::onResize(int width, int height) { +void +RendererCommon::onResize(int width, int height) +{ if ((video_fullscreen == 0) && (video_fullscreen_scale_maximized ? ((parentWidget->isMaximized() == false) && (main_window->isAncestorOf(parentWidget) && main_window->isMaximized() == false)) : 1)) { destination.setRect(0, 0, width, height); return; } double dx, dy, dw, dh, gsr; - double hw = width; - double hh = height; - double gw = source.width(); - double gh = source.height(); + double hw = width; + double hh = height; + double gw = source.width(); + double gh = source.height(); double hsr = hw / hh; switch (video_fullscreen_scale) { - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - integer_scale(&dw, &gw); - integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) { - gsr = 4.0 / 3.0; - } else { + case FULLSCR_SCALE_INT: gsr = gw / gh; - } + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + integer_scale(&dw, &gw); + integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) { + gsr = 4.0 / 3.0; + } else { + gsr = gw / gh; + } - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - destination.setRect(dx, dy, dw, dh); - break; - case FULLSCR_SCALE_FULL: - default: - destination.setRect(0, 0, hw, hh); - break; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + destination.setRect(dx, dy, dw, dh); + break; + case FULLSCR_SCALE_FULL: + default: + destination.setRect(0, 0, hw, hh); + break; } } -bool RendererCommon::eventDelegate(QEvent *event, bool& result) +bool +RendererCommon::eventDelegate(QEvent *event, bool &result) { - switch (event->type()) - { + switch (event->type()) { default: return false; case QEvent::KeyPress: diff --git a/src/qt/qt_renderercommon.hpp b/src/qt/qt_renderercommon.hpp index 4a1b18341..97370ea3f 100644 --- a/src/qt/qt_renderercommon.hpp +++ b/src/qt/qt_renderercommon.hpp @@ -22,22 +22,26 @@ public: virtual uint32_t getBytesPerRow() { return 2048 * 4; } - virtual std::vector> getBuffers() { std::vector> buffers; return buffers; } + virtual std::vector> getBuffers() + { + std::vector> buffers; + return buffers; + } /* Does renderer implement options dialog */ virtual bool hasOptions() const { return false; } /* Returns options dialog for renderer */ virtual QDialog *getOptions(QWidget *parent) { return nullptr; } /* Reloads options of renderer */ - virtual void reloadOptions() {} + virtual void reloadOptions() { } virtual bool hasBlitFunc() { return false; } - virtual void blit(int x, int y, int w, int h) {} + virtual void blit(int x, int y, int w, int h) { } protected: bool eventDelegate(QEvent *event, bool &result); - QRect source{0, 0, 0, 0}, destination; + QRect source { 0, 0, 0, 0 }, destination; QWidget *parentWidget { nullptr }; std::vector buf_usage; diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 2d32f24a8..d36a88f86 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -26,7 +26,7 @@ #include "qt_softwarerenderer.hpp" #include "qt_vulkanwindowrenderer.hpp" #ifdef Q_OS_WIN -#include "qt_d3d9renderer.hpp" +# include "qt_d3d9renderer.hpp" #endif #include "qt_mainwindow.hpp" @@ -63,7 +63,7 @@ struct mouseinputdata { }; static mouseinputdata mousedata; -extern "C" void macos_poll_mouse(); +extern "C" void macos_poll_mouse(); extern MainWindow *main_window; RendererStack::RendererStack(QWidget *parent, int monitor_index) : QStackedWidget(parent) @@ -89,8 +89,8 @@ RendererStack::RendererStack(QWidget *parent, int monitor_index) # ifdef WAYLAND if (!stricmp(mouse_type, "wayland")) { wl_init(); - this->mouse_poll_func = wl_mouse_poll; - this->mouse_capture_func = wl_mouse_capture; + this->mouse_poll_func = wl_mouse_poll; + this->mouse_capture_func = wl_mouse_capture; this->mouse_uncapture_func = wl_mouse_uncapture; } # endif @@ -146,7 +146,7 @@ RendererStack::mousePoll() mouse_y = mousedata.deltay; mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; if (this->mouse_poll_func) #endif @@ -258,10 +258,10 @@ RendererStack::switchRenderer(Renderer renderer) startblit(); if (current) { if ((current_vid_api == Renderer::Direct3D9 && renderer != Renderer::Direct3D9) - || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { + || (current_vid_api != Renderer::Direct3D9 && renderer == Renderer::Direct3D9)) { rendererWindow->finalize(); if (rendererWindow->hasBlitFunc()) { - while (directBlitting) {} + while (directBlitting) { } connect(this, &RendererStack::blit, this, &RendererStack::blitDummy, Qt::DirectConnection); disconnect(this, &RendererStack::blit, this, &RendererStack::blitRenderer); } else { @@ -277,7 +277,7 @@ RendererStack::switchRenderer(Renderer renderer) createRenderer(renderer); disconnect(this, &RendererStack::blit, this, &RendererStack::blitDummy); blitDummied = false; - QTimer::singleShot(1000, this, [this]() { blitDummied = false; } ); + QTimer::singleShot(1000, this, [this]() { blitDummied = false; }); }); rendererWindow->hasBlitFunc() ? current.reset() : current.release()->deleteLater(); @@ -354,65 +354,64 @@ RendererStack::createRenderer(Renderer renderer) } #ifdef Q_OS_WIN case Renderer::Direct3D9: - { - this->createWinId(); - auto hw = new D3D9Renderer(this, m_monitor_index); - rendererWindow = hw; - connect(hw, &D3D9Renderer::error, this, [this](QString str) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - connect(hw, &D3D9Renderer::initialized, this, [this]() - { - endblit(); - emit rendererChanged(); - }); - current.reset(hw); - break; - } + this->createWinId(); + auto hw = new D3D9Renderer(this, m_monitor_index); + rendererWindow = hw; + connect(hw, &D3D9Renderer::error, this, [this](QString str) { + auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize D3D9 renderer. Falling back to software rendering.\n\n") + str, QMessageBox::Ok); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->show(); + imagebufs = {}; + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + }); + connect(hw, &D3D9Renderer::initialized, this, [this]() { + endblit(); + emit rendererChanged(); + }); + current.reset(hw); + break; + } #endif #if QT_CONFIG(vulkan) case Renderer::Vulkan: - { - this->createWinId(); - VulkanWindowRenderer *hw = nullptr; - try { - hw = new VulkanWindowRenderer(this); - } catch(std::runtime_error& e) { - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", e.what() + QString("\nFalling back to software rendering."), QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - current.reset(nullptr); + { + this->createWinId(); + VulkanWindowRenderer *hw = nullptr; + try { + hw = new VulkanWindowRenderer(this); + } catch (std::runtime_error &e) { + auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", e.what() + QString("\nFalling back to software rendering."), QMessageBox::Ok); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->show(); + imagebufs = {}; + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + current.reset(nullptr); + break; + }; + rendererWindow = hw; + connect(this, &RendererStack::blitToRenderer, hw, &VulkanWindowRenderer::onBlit, Qt::QueuedConnection); + connect(hw, &VulkanWindowRenderer::rendererInitialized, [=]() { + /* Buffers are available only after initialization. */ + imagebufs = rendererWindow->getBuffers(); + endblit(); + emit rendererChanged(); + }); + connect(hw, &VulkanWindowRenderer::errorInitializing, [=]() { + /* Renderer could not initialize, fallback to software. */ + auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize Vulkan renderer.\nFalling back to software rendering."), QMessageBox::Ok); + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->show(); + imagebufs = {}; + QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); + }); + current.reset(this->createWindowContainer(hw, this)); break; - }; - rendererWindow = hw; - connect(this, &RendererStack::blitToRenderer, hw, &VulkanWindowRenderer::onBlit, Qt::QueuedConnection); - connect(hw, &VulkanWindowRenderer::rendererInitialized, [=]() { - /* Buffers are available only after initialization. */ - imagebufs = rendererWindow->getBuffers(); - endblit(); - emit rendererChanged(); - }); - connect(hw, &VulkanWindowRenderer::errorInitializing, [=]() { - /* Renderer could not initialize, fallback to software. */ - auto msgBox = new QMessageBox(QMessageBox::Critical, "86Box", QString("Failed to initialize Vulkan renderer.\nFalling back to software rendering."), QMessageBox::Ok); - msgBox->setAttribute(Qt::WA_DeleteOnClose); - msgBox->show(); - imagebufs = {}; - QTimer::singleShot(0, this, [this]() { switchRenderer(Renderer::Software); }); - }); - current.reset(this->createWindowContainer(hw, this)); - break; - } + } #endif } - if (current.get() == nullptr) return; + if (current.get() == nullptr) + return; current->setFocusPolicy(Qt::NoFocus); current->setFocusProxy(this); current->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -425,8 +424,7 @@ RendererStack::createRenderer(Renderer renderer) if (rendererWindow->hasBlitFunc()) { connect(this, &RendererStack::blit, this, &RendererStack::blitRenderer, Qt::DirectConnection); - } - else { + } else { connect(this, &RendererStack::blit, this, &RendererStack::blitCommon, Qt::DirectConnection); } @@ -447,7 +445,11 @@ RendererStack::blitDummy(int x, int y, int w, int h) void RendererStack::blitRenderer(int x, int y, int w, int h) { - if (blitDummied) { blitDummied = false; video_blit_complete_monitor(m_monitor_index); return; } + if (blitDummied) { + blitDummied = false; + video_blit_complete_monitor(m_monitor_index); + return; + } directBlitting = true; rendererWindow->blit(x, y, w, h); directBlitting = false; @@ -479,7 +481,8 @@ RendererStack::blitCommon(int x, int y, int w, int h) currentBuf = (currentBuf + 1) % imagebufs.size(); } -void RendererStack::closeEvent(QCloseEvent* event) +void +RendererStack::closeEvent(QCloseEvent *event) { if (cpu_thread_run == 1 || is_quit == 0) { event->accept(); @@ -490,7 +493,8 @@ void RendererStack::closeEvent(QCloseEvent* event) main_window->close(); } -void RendererStack::changeEvent(QEvent *event) +void +RendererStack::changeEvent(QEvent *event) { if (m_monitor_index != 0 && isVisible()) { monitor_settings[m_monitor_index].mon_window_maximized = isMaximized(); diff --git a/src/qt/qt_rendererstack.hpp b/src/qt/qt_rendererstack.hpp index 4d06ed1cf..baee5ea9f 100644 --- a/src/qt/qt_rendererstack.hpp +++ b/src/qt/qt_rendererstack.hpp @@ -32,7 +32,7 @@ public: void wheelEvent(QWheelEvent *event) override; void leaveEvent(QEvent *event) override; void closeEvent(QCloseEvent *event) override; - void changeEvent(QEvent* event) override; + void changeEvent(QEvent *event) override; void resizeEvent(QResizeEvent *event) override { onResize(event->size().width(), event->size().height()); @@ -75,10 +75,10 @@ public: rendererWindow->onResize(width, height); } - void (*mouse_poll_func)() = nullptr; + void (*mouse_poll_func)() = nullptr; void (*mouse_capture_func)(QWindow *window) = nullptr; - void (*mouse_uncapture_func)() = nullptr; - void (*mouse_exit_func)() = nullptr; + void (*mouse_uncapture_func)() = nullptr; + void (*mouse_exit_func)() = nullptr; signals: void blitToRenderer(int buf_idx, int x, int y, int w, int h); @@ -98,8 +98,8 @@ private: int x, y, w, h, sx, sy, sw, sh; - int currentBuf = 0; - int isMouseDown = 0; + int currentBuf = 0; + int isMouseDown = 0; int m_monitor_index = 0; Renderer current_vid_api = Renderer::None; @@ -108,7 +108,7 @@ private: RendererCommon *rendererWindow { nullptr }; std::unique_ptr current; - std::atomic directBlitting{false}; + std::atomic directBlitting { false }; }; #endif // QT_RENDERERCONTAINER_HPP diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c index 57b9538e9..54eca952b 100644 --- a/src/qt/qt_sdl.c +++ b/src/qt/qt_sdl.c @@ -71,133 +71,130 @@ #include "qt_sdl.h" -#define RENDERER_FULL_SCREEN 1 -#define RENDERER_HARDWARE 2 -#define RENDERER_OPENGL 4 +#define RENDERER_FULL_SCREEN 1 +#define RENDERER_HARDWARE 2 +#define RENDERER_OPENGL 4 +static SDL_Window *sdl_win = NULL; +static SDL_Renderer *sdl_render = NULL; +static SDL_Texture *sdl_tex = NULL; +static int sdl_w, sdl_h; +static int sdl_fs, sdl_flags = -1; +static int cur_w, cur_h; +static int cur_ww = 0, cur_wh = 0; +static volatile int sdl_enabled = 0; +static SDL_mutex *sdl_mutex = NULL; -static SDL_Window *sdl_win = NULL; -static SDL_Renderer *sdl_render = NULL; -static SDL_Texture *sdl_tex = NULL; -static int sdl_w, sdl_h; -static int sdl_fs, sdl_flags = -1; -static int cur_w, cur_h; -static int cur_ww = 0, cur_wh = 0; -static volatile int sdl_enabled = 0; -static SDL_mutex* sdl_mutex = NULL; +static const uint16_t sdl_to_xt[0x200] = { + [SDL_SCANCODE_ESCAPE] = 0x01, + [SDL_SCANCODE_1] = 0x02, + [SDL_SCANCODE_2] = 0x03, + [SDL_SCANCODE_3] = 0x04, + [SDL_SCANCODE_4] = 0x05, + [SDL_SCANCODE_5] = 0x06, + [SDL_SCANCODE_6] = 0x07, + [SDL_SCANCODE_7] = 0x08, + [SDL_SCANCODE_8] = 0x09, + [SDL_SCANCODE_9] = 0x0A, + [SDL_SCANCODE_0] = 0x0B, + [SDL_SCANCODE_MINUS] = 0x0C, + [SDL_SCANCODE_EQUALS] = 0x0D, + [SDL_SCANCODE_BACKSPACE] = 0x0E, + [SDL_SCANCODE_TAB] = 0x0F, + [SDL_SCANCODE_Q] = 0x10, + [SDL_SCANCODE_W] = 0x11, + [SDL_SCANCODE_E] = 0x12, + [SDL_SCANCODE_R] = 0x13, + [SDL_SCANCODE_T] = 0x14, + [SDL_SCANCODE_Y] = 0x15, + [SDL_SCANCODE_U] = 0x16, + [SDL_SCANCODE_I] = 0x17, + [SDL_SCANCODE_O] = 0x18, + [SDL_SCANCODE_P] = 0x19, + [SDL_SCANCODE_LEFTBRACKET] = 0x1A, + [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, + [SDL_SCANCODE_RETURN] = 0x1C, + [SDL_SCANCODE_LCTRL] = 0x1D, + [SDL_SCANCODE_A] = 0x1E, + [SDL_SCANCODE_S] = 0x1F, + [SDL_SCANCODE_D] = 0x20, + [SDL_SCANCODE_F] = 0x21, + [SDL_SCANCODE_G] = 0x22, + [SDL_SCANCODE_H] = 0x23, + [SDL_SCANCODE_J] = 0x24, + [SDL_SCANCODE_K] = 0x25, + [SDL_SCANCODE_L] = 0x26, + [SDL_SCANCODE_SEMICOLON] = 0x27, + [SDL_SCANCODE_APOSTROPHE] = 0x28, + [SDL_SCANCODE_GRAVE] = 0x29, + [SDL_SCANCODE_LSHIFT] = 0x2A, + [SDL_SCANCODE_BACKSLASH] = 0x2B, + [SDL_SCANCODE_Z] = 0x2C, + [SDL_SCANCODE_X] = 0x2D, + [SDL_SCANCODE_C] = 0x2E, + [SDL_SCANCODE_V] = 0x2F, + [SDL_SCANCODE_B] = 0x30, + [SDL_SCANCODE_N] = 0x31, + [SDL_SCANCODE_M] = 0x32, + [SDL_SCANCODE_COMMA] = 0x33, + [SDL_SCANCODE_PERIOD] = 0x34, + [SDL_SCANCODE_SLASH] = 0x35, + [SDL_SCANCODE_RSHIFT] = 0x36, + [SDL_SCANCODE_KP_MULTIPLY] = 0x37, + [SDL_SCANCODE_LALT] = 0x38, + [SDL_SCANCODE_SPACE] = 0x39, + [SDL_SCANCODE_CAPSLOCK] = 0x3A, + [SDL_SCANCODE_F1] = 0x3B, + [SDL_SCANCODE_F2] = 0x3C, + [SDL_SCANCODE_F3] = 0x3D, + [SDL_SCANCODE_F4] = 0x3E, + [SDL_SCANCODE_F5] = 0x3F, + [SDL_SCANCODE_F6] = 0x40, + [SDL_SCANCODE_F7] = 0x41, + [SDL_SCANCODE_F8] = 0x42, + [SDL_SCANCODE_F9] = 0x43, + [SDL_SCANCODE_F10] = 0x44, + [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, + [SDL_SCANCODE_SCROLLLOCK] = 0x46, + [SDL_SCANCODE_HOME] = 0x147, + [SDL_SCANCODE_UP] = 0x148, + [SDL_SCANCODE_PAGEUP] = 0x149, + [SDL_SCANCODE_KP_MINUS] = 0x4A, + [SDL_SCANCODE_LEFT] = 0x14B, + [SDL_SCANCODE_KP_5] = 0x4C, + [SDL_SCANCODE_RIGHT] = 0x14D, + [SDL_SCANCODE_KP_PLUS] = 0x4E, + [SDL_SCANCODE_END] = 0x14F, + [SDL_SCANCODE_DOWN] = 0x150, + [SDL_SCANCODE_PAGEDOWN] = 0x151, + [SDL_SCANCODE_INSERT] = 0x152, + [SDL_SCANCODE_DELETE] = 0x153, + [SDL_SCANCODE_F11] = 0x57, + [SDL_SCANCODE_F12] = 0x58, -static const uint16_t sdl_to_xt[0x200] = - { - [SDL_SCANCODE_ESCAPE] = 0x01, - [SDL_SCANCODE_1] = 0x02, - [SDL_SCANCODE_2] = 0x03, - [SDL_SCANCODE_3] = 0x04, - [SDL_SCANCODE_4] = 0x05, - [SDL_SCANCODE_5] = 0x06, - [SDL_SCANCODE_6] = 0x07, - [SDL_SCANCODE_7] = 0x08, - [SDL_SCANCODE_8] = 0x09, - [SDL_SCANCODE_9] = 0x0A, - [SDL_SCANCODE_0] = 0x0B, - [SDL_SCANCODE_MINUS] = 0x0C, - [SDL_SCANCODE_EQUALS] = 0x0D, - [SDL_SCANCODE_BACKSPACE] = 0x0E, - [SDL_SCANCODE_TAB] = 0x0F, - [SDL_SCANCODE_Q] = 0x10, - [SDL_SCANCODE_W] = 0x11, - [SDL_SCANCODE_E] = 0x12, - [SDL_SCANCODE_R] = 0x13, - [SDL_SCANCODE_T] = 0x14, - [SDL_SCANCODE_Y] = 0x15, - [SDL_SCANCODE_U] = 0x16, - [SDL_SCANCODE_I] = 0x17, - [SDL_SCANCODE_O] = 0x18, - [SDL_SCANCODE_P] = 0x19, - [SDL_SCANCODE_LEFTBRACKET] = 0x1A, - [SDL_SCANCODE_RIGHTBRACKET] = 0x1B, - [SDL_SCANCODE_RETURN] = 0x1C, - [SDL_SCANCODE_LCTRL] = 0x1D, - [SDL_SCANCODE_A] = 0x1E, - [SDL_SCANCODE_S] = 0x1F, - [SDL_SCANCODE_D] = 0x20, - [SDL_SCANCODE_F] = 0x21, - [SDL_SCANCODE_G] = 0x22, - [SDL_SCANCODE_H] = 0x23, - [SDL_SCANCODE_J] = 0x24, - [SDL_SCANCODE_K] = 0x25, - [SDL_SCANCODE_L] = 0x26, - [SDL_SCANCODE_SEMICOLON] = 0x27, - [SDL_SCANCODE_APOSTROPHE] = 0x28, - [SDL_SCANCODE_GRAVE] = 0x29, - [SDL_SCANCODE_LSHIFT] = 0x2A, - [SDL_SCANCODE_BACKSLASH] = 0x2B, - [SDL_SCANCODE_Z] = 0x2C, - [SDL_SCANCODE_X] = 0x2D, - [SDL_SCANCODE_C] = 0x2E, - [SDL_SCANCODE_V] = 0x2F, - [SDL_SCANCODE_B] = 0x30, - [SDL_SCANCODE_N] = 0x31, - [SDL_SCANCODE_M] = 0x32, - [SDL_SCANCODE_COMMA] = 0x33, - [SDL_SCANCODE_PERIOD] = 0x34, - [SDL_SCANCODE_SLASH] = 0x35, - [SDL_SCANCODE_RSHIFT] = 0x36, - [SDL_SCANCODE_KP_MULTIPLY] = 0x37, - [SDL_SCANCODE_LALT] = 0x38, - [SDL_SCANCODE_SPACE] = 0x39, - [SDL_SCANCODE_CAPSLOCK] = 0x3A, - [SDL_SCANCODE_F1] = 0x3B, - [SDL_SCANCODE_F2] = 0x3C, - [SDL_SCANCODE_F3] = 0x3D, - [SDL_SCANCODE_F4] = 0x3E, - [SDL_SCANCODE_F5] = 0x3F, - [SDL_SCANCODE_F6] = 0x40, - [SDL_SCANCODE_F7] = 0x41, - [SDL_SCANCODE_F8] = 0x42, - [SDL_SCANCODE_F9] = 0x43, - [SDL_SCANCODE_F10] = 0x44, - [SDL_SCANCODE_NUMLOCKCLEAR] = 0x45, - [SDL_SCANCODE_SCROLLLOCK] = 0x46, - [SDL_SCANCODE_HOME] = 0x147, - [SDL_SCANCODE_UP] = 0x148, - [SDL_SCANCODE_PAGEUP] = 0x149, - [SDL_SCANCODE_KP_MINUS] = 0x4A, - [SDL_SCANCODE_LEFT] = 0x14B, - [SDL_SCANCODE_KP_5] = 0x4C, - [SDL_SCANCODE_RIGHT] = 0x14D, - [SDL_SCANCODE_KP_PLUS] = 0x4E, - [SDL_SCANCODE_END] = 0x14F, - [SDL_SCANCODE_DOWN] = 0x150, - [SDL_SCANCODE_PAGEDOWN] = 0x151, - [SDL_SCANCODE_INSERT] = 0x152, - [SDL_SCANCODE_DELETE] = 0x153, - [SDL_SCANCODE_F11] = 0x57, - [SDL_SCANCODE_F12] = 0x58, + [SDL_SCANCODE_KP_ENTER] = 0x11c, + [SDL_SCANCODE_RCTRL] = 0x11d, + [SDL_SCANCODE_KP_DIVIDE] = 0x135, + [SDL_SCANCODE_RALT] = 0x138, + [SDL_SCANCODE_KP_9] = 0x49, + [SDL_SCANCODE_KP_8] = 0x48, + [SDL_SCANCODE_KP_7] = 0x47, + [SDL_SCANCODE_KP_6] = 0x4D, + [SDL_SCANCODE_KP_4] = 0x4B, + [SDL_SCANCODE_KP_3] = 0x51, + [SDL_SCANCODE_KP_2] = 0x50, + [SDL_SCANCODE_KP_1] = 0x4F, + [SDL_SCANCODE_KP_0] = 0x52, + [SDL_SCANCODE_KP_PERIOD] = 0x53, - [SDL_SCANCODE_KP_ENTER] = 0x11c, - [SDL_SCANCODE_RCTRL] = 0x11d, - [SDL_SCANCODE_KP_DIVIDE] = 0x135, - [SDL_SCANCODE_RALT] = 0x138, - [SDL_SCANCODE_KP_9] = 0x49, - [SDL_SCANCODE_KP_8] = 0x48, - [SDL_SCANCODE_KP_7] = 0x47, - [SDL_SCANCODE_KP_6] = 0x4D, - [SDL_SCANCODE_KP_4] = 0x4B, - [SDL_SCANCODE_KP_3] = 0x51, - [SDL_SCANCODE_KP_2] = 0x50, - [SDL_SCANCODE_KP_1] = 0x4F, - [SDL_SCANCODE_KP_0] = 0x52, - [SDL_SCANCODE_KP_PERIOD] = 0x53, - - [SDL_SCANCODE_LGUI] = 0x15B, - [SDL_SCANCODE_RGUI] = 0x15C, - [SDL_SCANCODE_APPLICATION] = 0x15D, - [SDL_SCANCODE_PRINTSCREEN] = 0x137, - [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, + [SDL_SCANCODE_LGUI] = 0x15B, + [SDL_SCANCODE_RGUI] = 0x15C, + [SDL_SCANCODE_APPLICATION] = 0x15D, + [SDL_SCANCODE_PRINTSCREEN] = 0x137, + [SDL_SCANCODE_NONUSBACKSLASH] = 0x56, }; -typedef struct mouseinputdata -{ +typedef struct mouseinputdata { int deltax, deltay, deltaz; int mousebuttons; } mouseinputdata; @@ -213,88 +210,86 @@ sdl_log(const char *fmt, ...) va_list ap; if (sdl_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define sdl_log(fmt, ...) +# define sdl_log(fmt, ...) #endif - static void sdl_integer_scale(double *d, double *g) { double ratio; if (*d > *g) { - ratio = floor(*d / *g); - *d = *g * ratio; + ratio = floor(*d / *g); + *d = *g * ratio; } else { - ratio = ceil(*d / *g); - *d = *g / ratio; + ratio = ceil(*d / *g); + *d = *g / ratio; } } - static void sdl_stretch(int *w, int *h, int *x, int *y) { double hw, gw, hh, gh, dx, dy, dw, dh, gsr, hsr; - hw = (double) sdl_w; - hh = (double) sdl_h; - gw = (double) *w; - gh = (double) *h; + hw = (double) sdl_w; + hh = (double) sdl_h; + gw = (double) *w; + gh = (double) *h; hsr = hw / hh; switch (video_fullscreen_scale) { - case FULLSCR_SCALE_FULL: - default: - *w = sdl_w; - *h = sdl_h; - *x = 0; - *y = 0; - break; - case FULLSCR_SCALE_43: - case FULLSCR_SCALE_KEEPRATIO: - if (video_fullscreen_scale == FULLSCR_SCALE_43) - gsr = 4.0 / 3.0; - else - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; - case FULLSCR_SCALE_INT: - gsr = gw / gh; - if (gsr <= hsr) { - dw = hh * gsr; - dh = hh; - } else { - dw = hw; - dh = hw / gsr; - } - sdl_integer_scale(&dw, &gw); - sdl_integer_scale(&dh, &gh); - dx = (hw - dw) / 2.0; - dy = (hh - dh) / 2.0; - *w = (int) dw; - *h = (int) dh; - *x = (int) dx; - *y = (int) dy; - break; + case FULLSCR_SCALE_FULL: + default: + *w = sdl_w; + *h = sdl_h; + *x = 0; + *y = 0; + break; + case FULLSCR_SCALE_43: + case FULLSCR_SCALE_KEEPRATIO: + if (video_fullscreen_scale == FULLSCR_SCALE_43) + gsr = 4.0 / 3.0; + else + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; + case FULLSCR_SCALE_INT: + gsr = gw / gh; + if (gsr <= hsr) { + dw = hh * gsr; + dh = hh; + } else { + dw = hw; + dh = hw / gsr; + } + sdl_integer_scale(&dw, &gw); + sdl_integer_scale(&dh, &gh); + dx = (hw - dw) / 2.0; + dy = (hh - dh) / 2.0; + *w = (int) dw; + *h = (int) dh; + *x = (int) dx; + *y = (int) dy; + break; } } @@ -302,8 +297,8 @@ static void sdl_blit(int x, int y, int w, int h) { SDL_Rect r_src; - void *pixeldata; - int ret, pitch; + void *pixeldata; + int ret, pitch; if (!sdl_enabled || (x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (w > 2048) || (h > 2048) || (buffer32 == NULL) || (sdl_render == NULL) || (sdl_tex == NULL)) { video_blit_complete(); @@ -338,48 +333,45 @@ sdl_blit(int x, int y, int w, int h) SDL_UnlockMutex(sdl_mutex); } - static void sdl_destroy_window(void) { if (sdl_win != NULL) { - SDL_DestroyWindow(sdl_win); - sdl_win = NULL; + SDL_DestroyWindow(sdl_win); + sdl_win = NULL; } } - static void sdl_destroy_texture(void) { if (sdl_tex != NULL) { - SDL_DestroyTexture(sdl_tex); - sdl_tex = NULL; + SDL_DestroyTexture(sdl_tex); + sdl_tex = NULL; } /* SDL_DestroyRenderer also automatically destroys all associated textures. */ if (sdl_render != NULL) { - SDL_DestroyRenderer(sdl_render); - sdl_render = NULL; + SDL_DestroyRenderer(sdl_render); + sdl_render = NULL; } } - void sdl_close(void) { if (sdl_mutex != NULL) - SDL_LockMutex(sdl_mutex); + SDL_LockMutex(sdl_mutex); /* Unregister our renderer! */ video_setblit(NULL); if (sdl_enabled) - sdl_enabled = 0; + sdl_enabled = 0; if (sdl_mutex != NULL) { - SDL_DestroyMutex(sdl_mutex); - sdl_mutex = NULL; + SDL_DestroyMutex(sdl_mutex); + sdl_mutex = NULL; } sdl_destroy_texture(); @@ -390,8 +382,10 @@ sdl_close(void) sdl_flags = -1; } -static void sdl_select_best_hw_driver(void) { - int i; +static void +sdl_select_best_hw_driver(void) +{ + int i; SDL_RendererInfo renderInfo; for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) { @@ -414,7 +408,7 @@ sdl_init_texture(void) } sdl_tex = SDL_CreateTexture(sdl_render, SDL_PIXELFORMAT_ARGB8888, - SDL_TEXTUREACCESS_STREAMING, (2048), (2048)); + SDL_TEXTUREACCESS_STREAMING, (2048), (2048)); if (sdl_render == NULL) { sdl_log("SDL: unable to SDL_CreateRenderer (%s)\n", SDL_GetError()); @@ -424,7 +418,6 @@ sdl_init_texture(void) } } - static void sdl_reinit_texture(void) { @@ -435,10 +428,11 @@ sdl_reinit_texture(void) sdl_init_texture(); } - -void sdl_set_fs(int fs) { +void +sdl_set_fs(int fs) +{ SDL_SetWindowFullscreen(sdl_win, fs ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); - SDL_SetRelativeMouseMode((SDL_bool)mouse_capture); + SDL_SetRelativeMouseMode((SDL_bool) mouse_capture); sdl_fs = fs; @@ -451,11 +445,10 @@ void sdl_set_fs(int fs) { sdl_reinit_texture(); } - static int -sdl_init_common(void* win, int flags) +sdl_init_common(void *win, int flags) { - wchar_t temp[128]; + wchar_t temp[128]; SDL_version ver; sdl_log("SDL: init (fs=%d)\n", 0); @@ -467,7 +460,7 @@ sdl_init_common(void* win, int flags) /* Initialize the SDL system. */ if (SDL_Init(SDL_INIT_VIDEO) < 0) { sdl_log("SDL: initialization failed (%s)\n", SDL_GetError()); - return(0); + return (0); } if (flags & RENDERER_HARDWARE) { @@ -481,10 +474,10 @@ sdl_init_common(void* win, int flags) SDL_DisplayMode dm; if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { sdl_log("SDL: SDL_GetDesktopDisplayMode failed (%s)\n", SDL_GetError()); - return(0); + return (0); } - sdl_w = dm.w; - sdl_h = dm.h; + sdl_w = dm.w; + sdl_h = dm.h; sdl_flags = flags; sdl_win = SDL_CreateWindow("86Box renderer", 640, 480, 100, 100, sdl_flags); @@ -501,50 +494,45 @@ sdl_init_common(void* win, int flags) video_setblit(sdl_blit); sdl_enabled = 1; - sdl_mutex = SDL_CreateMutex(); + sdl_mutex = SDL_CreateMutex(); - return(1); + return (1); } - int -sdl_inits(void* win) +sdl_inits(void *win) { return sdl_init_common(win, 0); } - int -sdl_inith(void* win) +sdl_inith(void *win) { return sdl_init_common(win, RENDERER_HARDWARE); } - int -sdl_initho(void* win) +sdl_initho(void *win) { return sdl_init_common(win, RENDERER_HARDWARE | RENDERER_OPENGL); } - int sdl_pause(void) { - return(0); + return (0); } - void sdl_resize(int w, int h) { int ww = 0, wh = 0; if (video_fullscreen & 2) - return; + return; if ((w == cur_w) && (h == cur_h)) - return; + return; SDL_LockMutex(sdl_mutex); @@ -552,8 +540,8 @@ sdl_resize(int w, int h) wh = h; if (sdl_fs) { -// sdl_stretch(&ww, &wh, &wx, &wy); -// MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); + // sdl_stretch(&ww, &wh, &wx, &wy); + // MoveWindow(hwndRender, wx, wy, ww, wh, TRUE); } cur_w = w; @@ -568,12 +556,11 @@ sdl_resize(int w, int h) SDL_UnlockMutex(sdl_mutex); } - void sdl_enable(int enable) { if (sdl_flags == -1) - return; + return; SDL_LockMutex(sdl_mutex); sdl_enabled = !!enable; @@ -586,126 +573,115 @@ sdl_enable(int enable) SDL_UnlockMutex(sdl_mutex); } - void sdl_reload(void) { if (sdl_flags & RENDERER_HARDWARE) { - SDL_LockMutex(sdl_mutex); + SDL_LockMutex(sdl_mutex); - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); - sdl_reinit_texture(); + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, video_filter_method ? "1" : "0"); + sdl_reinit_texture(); - SDL_UnlockMutex(sdl_mutex); + SDL_UnlockMutex(sdl_mutex); } } static int mouse_inside = 0; -enum sdl_main_status sdl_main() { - int ret = SdlMainOk; - SDL_Rect r_src; +enum sdl_main_status +sdl_main() +{ + int ret = SdlMainOk; + SDL_Rect r_src; SDL_Event event; - while (SDL_PollEvent(&event)) - { - switch(event.type) - { - case SDL_QUIT: - ret = SdlMainQuit; - break; - case SDL_MOUSEWHEEL: - { - if (mouse_capture || video_fullscreen) - { - if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + ret = SdlMainQuit; + break; + case SDL_MOUSEWHEEL: { - event.wheel.x *= -1; - event.wheel.y *= -1; + if (mouse_capture || video_fullscreen) { + if (event.wheel.direction == SDL_MOUSEWHEEL_FLIPPED) { + event.wheel.x *= -1; + event.wheel.y *= -1; + } + mousedata.deltaz = event.wheel.y; + } + break; } - mousedata.deltaz = event.wheel.y; - } - break; - } - case SDL_MOUSEMOTION: - { - if (mouse_capture || video_fullscreen) - { - mousedata.deltax += event.motion.xrel; - mousedata.deltay += event.motion.yrel; - } - break; - } - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - { - if ((event.button.button == SDL_BUTTON_LEFT) - && !(mouse_capture || video_fullscreen) - && event.button.state == SDL_RELEASED - && mouse_inside) - { - plat_mouse_capture(1); - break; - } - if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) - { - plat_mouse_capture(0); - break; - } - if (mouse_capture || video_fullscreen) - { - int buttonmask = 0; + case SDL_MOUSEMOTION: + { + if (mouse_capture || video_fullscreen) { + mousedata.deltax += event.motion.xrel; + mousedata.deltay += event.motion.yrel; + } + break; + } + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + { + if ((event.button.button == SDL_BUTTON_LEFT) + && !(mouse_capture || video_fullscreen) + && event.button.state == SDL_RELEASED + && mouse_inside) { + plat_mouse_capture(1); + break; + } + if (mouse_get_buttons() < 3 && event.button.button == SDL_BUTTON_MIDDLE && !video_fullscreen) { + plat_mouse_capture(0); + break; + } + if (mouse_capture || video_fullscreen) { + int buttonmask = 0; - switch(event.button.button) - { - case SDL_BUTTON_LEFT: - buttonmask = 1; - break; - case SDL_BUTTON_RIGHT: - buttonmask = 2; - break; - case SDL_BUTTON_MIDDLE: - buttonmask = 4; + switch (event.button.button) { + case SDL_BUTTON_LEFT: + buttonmask = 1; + break; + case SDL_BUTTON_RIGHT: + buttonmask = 2; + break; + case SDL_BUTTON_MIDDLE: + buttonmask = 4; + break; + } + if (event.button.state == SDL_PRESSED) { + mousedata.mousebuttons |= buttonmask; + } else + mousedata.mousebuttons &= ~buttonmask; + } break; } - if (event.button.state == SDL_PRESSED) + case SDL_RENDER_DEVICE_RESET: + case SDL_RENDER_TARGETS_RESET: { - mousedata.mousebuttons |= buttonmask; + sdl_reinit_texture(); + break; + } + case SDL_KEYDOWN: + case SDL_KEYUP: + { + uint16_t xtkey = 0; + switch (event.key.keysym.scancode) { + default: + xtkey = sdl_to_xt[event.key.keysym.scancode]; + break; + } + keyboard_input(event.key.state == SDL_PRESSED, xtkey); } - else mousedata.mousebuttons &= ~buttonmask; - } - break; - } - case SDL_RENDER_DEVICE_RESET: - case SDL_RENDER_TARGETS_RESET: - { - sdl_reinit_texture(); - break; - } - case SDL_KEYDOWN: - case SDL_KEYUP: - { - uint16_t xtkey = 0; - switch(event.key.keysym.scancode) - { - default: - xtkey = sdl_to_xt[event.key.keysym.scancode]; break; - } - keyboard_input(event.key.state == SDL_PRESSED, xtkey); - } - break; - case SDL_WINDOWEVENT: - { - switch (event.window.event) - { - case SDL_WINDOWEVENT_ENTER: - mouse_inside = 1; - break; - case SDL_WINDOWEVENT_LEAVE: - mouse_inside = 0; - break; - } - } + case SDL_WINDOWEVENT: + { + switch (event.window.event) { + case SDL_WINDOWEVENT_ENTER: + mouse_inside = 1; + break; + case SDL_WINDOWEVENT_LEAVE: + mouse_inside = 0; + break; + } + } } } @@ -719,14 +695,18 @@ enum sdl_main_status sdl_main() { return ret; } -void sdl_mouse_capture(int on) { - SDL_SetRelativeMouseMode((SDL_bool)on); +void +sdl_mouse_capture(int on) +{ + SDL_SetRelativeMouseMode((SDL_bool) on); } -void sdl_mouse_poll() { - mouse_x = mousedata.deltax; - mouse_y = mousedata.deltay; - mouse_z = mousedata.deltaz; +void +sdl_mouse_poll() +{ + mouse_x = mousedata.deltax; + mouse_y = mousedata.deltay; + mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; } diff --git a/src/qt/qt_sdl.h b/src/qt/qt_sdl.h index 02fd47ddf..684e6ccd0 100644 --- a/src/qt/qt_sdl.h +++ b/src/qt/qt_sdl.h @@ -47,18 +47,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef WIN_SDL_H -# define WIN_SDL_H +#define WIN_SDL_H -extern void* sdl_win_handle; -extern void sdl_close(void); -extern int sdl_inits(); -extern int sdl_inith(); -extern int sdl_initho(); -extern int sdl_pause(void); -extern void sdl_resize(int w, int h); -extern void sdl_enable(int enable); -extern void sdl_set_fs(int fs); -extern void sdl_reload(void); +extern void *sdl_win_handle; +extern void sdl_close(void); +extern int sdl_inits(); +extern int sdl_inith(); +extern int sdl_initho(); +extern int sdl_pause(void); +extern void sdl_resize(int w, int h); +extern void sdl_enable(int enable); +extern void sdl_set_fs(int fs); +extern void sdl_reload(void); enum sdl_main_status { SdlMainOk, @@ -70,4 +70,4 @@ extern enum sdl_main_status sdl_main(); extern void sdl_mouse_capture(int on); extern void sdl_mouse_poll(); -#endif /*WIN_SDL_H*/ +#endif /*WIN_SDL_H*/ diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index 290b95982..b42b20786 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -35,8 +35,7 @@ #include "qt_harddrive_common.hpp" #include "qt_settings_bus_tracking.hpp" -extern "C" -{ +extern "C" { #include <86box/86box.h> } @@ -48,10 +47,14 @@ extern "C" class SettingsModel : public QAbstractListModel { public: - SettingsModel(QObject* parent) : QAbstractListModel(parent) {} + SettingsModel(QObject *parent) + : QAbstractListModel(parent) + { + } QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + private: QStringList pages = { "Machine", @@ -81,44 +84,49 @@ private: }; }; -QVariant SettingsModel::data(const QModelIndex &index, int role) const { +QVariant +SettingsModel::data(const QModelIndex &index, int role) const +{ Q_ASSERT(checkIndex(index, QAbstractItemModel::CheckIndexOption::IndexIsValid | QAbstractItemModel::CheckIndexOption::ParentIsInvalid)); switch (role) { - case Qt::DisplayRole: - return tr(pages.at(index.row()).toUtf8().data()); - case Qt::DecorationRole: - return QIcon(QString("%1/%2.ico").arg(ProgSettings::getIconSetPath(), page_icons[index.row()])); - default: - return {}; + case Qt::DisplayRole: + return tr(pages.at(index.row()).toUtf8().data()); + case Qt::DecorationRole: + return QIcon(QString("%1/%2.ico").arg(ProgSettings::getIconSetPath(), page_icons[index.row()])); + default: + return {}; } } -int SettingsModel::rowCount(const QModelIndex &parent) const { +int +SettingsModel::rowCount(const QModelIndex &parent) const +{ (void) parent; return pages.size(); } -Settings* Settings::settings = nullptr;; -Settings::Settings(QWidget *parent) : - QDialog(parent), - ui(new Ui::Settings) +Settings *Settings::settings = nullptr; +; +Settings::Settings(QWidget *parent) + : QDialog(parent) + , ui(new Ui::Settings) { ui->setupUi(this); ui->listView->setModel(new SettingsModel(this)); Harddrives::busTrackClass = new SettingsBusTracking; - machine = new SettingsMachine(this); - display = new SettingsDisplay(this); - input = new SettingsInput(this); - sound = new SettingsSound(this); - network = new SettingsNetwork(this); - ports = new SettingsPorts(this); - storageControllers = new SettingsStorageControllers(this); - harddisks = new SettingsHarddisks(this); - floppyCdrom = new SettingsFloppyCDROM(this); - otherRemovable = new SettingsOtherRemovable(this); - otherPeripherals = new SettingsOtherPeripherals(this); + machine = new SettingsMachine(this); + display = new SettingsDisplay(this); + input = new SettingsInput(this); + sound = new SettingsSound(this); + network = new SettingsNetwork(this); + ports = new SettingsPorts(this); + storageControllers = new SettingsStorageControllers(this); + harddisks = new SettingsHarddisks(this); + floppyCdrom = new SettingsFloppyCDROM(this); + otherRemovable = new SettingsOtherRemovable(this); + otherPeripherals = new SettingsOtherPeripherals(this); ui->stackedWidget->addWidget(machine); ui->stackedWidget->addWidget(display); @@ -153,10 +161,12 @@ Settings::~Settings() delete ui; delete Harddrives::busTrackClass; Harddrives::busTrackClass = nullptr; - Settings::settings = nullptr; + Settings::settings = nullptr; } -void Settings::save() { +void +Settings::save() +{ machine->save(); display->save(); input->save(); @@ -170,12 +180,12 @@ void Settings::save() { otherPeripherals->save(); } -void Settings::accept() +void +Settings::accept() { - if (confirm_save && !settings_only) - { + if (confirm_save && !settings_only) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", QStringLiteral("%1\n\n%2").arg(tr("Do you want to save the settings?"), tr("This will hard reset the emulated machine.")), QMessageBox::Save | QMessageBox::Cancel, this); - QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); + QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_save); QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { diff --git a/src/qt/qt_settings.hpp b/src/qt/qt_settings.hpp index 7e0a78cfa..8603c42b6 100644 --- a/src/qt/qt_settings.hpp +++ b/src/qt/qt_settings.hpp @@ -19,32 +19,31 @@ class SettingsFloppyCDROM; class SettingsOtherRemovable; class SettingsOtherPeripherals; -class Settings : public QDialog -{ +class Settings : public QDialog { Q_OBJECT public: - explicit Settings(QWidget *parent = nullptr); + explicit Settings(QWidget *parent = nullptr); ~Settings(); - void save(); + void save(); - static Settings* settings; + static Settings *settings; protected slots: - void accept() override; + void accept() override; private: - Ui::Settings *ui; - SettingsMachine* machine; - SettingsDisplay* display; - SettingsInput* input; - SettingsSound* sound; - SettingsNetwork* network; - SettingsPorts* ports; - SettingsStorageControllers* storageControllers; - SettingsHarddisks* harddisks; - SettingsFloppyCDROM* floppyCdrom; - SettingsOtherRemovable* otherRemovable; - SettingsOtherPeripherals* otherPeripherals; + Ui::Settings *ui; + SettingsMachine *machine; + SettingsDisplay *display; + SettingsInput *input; + SettingsSound *sound; + SettingsNetwork *network; + SettingsPorts *ports; + SettingsStorageControllers *storageControllers; + SettingsHarddisks *harddisks; + SettingsFloppyCDROM *floppyCdrom; + SettingsOtherRemovable *otherRemovable; + SettingsOtherPeripherals *otherPeripherals; }; #endif // QT_SETTINGS_HPP diff --git a/src/qt/qt_settings_bus_tracking.cpp b/src/qt/qt_settings_bus_tracking.cpp index a1d8e3369..c22b8b10b 100644 --- a/src/qt/qt_settings_bus_tracking.cpp +++ b/src/qt/qt_settings_bus_tracking.cpp @@ -24,14 +24,13 @@ #include "86box/hdd.h" #include "qt_settings_bus_tracking.hpp" - SettingsBusTracking::SettingsBusTracking() { int i; - mfm_tracking = 0x0000000000000000ULL; + mfm_tracking = 0x0000000000000000ULL; esdi_tracking = 0x0000000000000000ULL; - xta_tracking = 0x0000000000000000ULL; + xta_tracking = 0x0000000000000000ULL; for (i = 0; i < 8; i++) { if (i < 4) @@ -41,7 +40,6 @@ SettingsBusTracking::SettingsBusTracking() } } - uint8_t SettingsBusTracking::next_free_mfm_channel() { @@ -54,7 +52,6 @@ SettingsBusTracking::next_free_mfm_channel() return CHANNEL_NONE; } - uint8_t SettingsBusTracking::next_free_esdi_channel() { @@ -67,7 +64,6 @@ SettingsBusTracking::next_free_esdi_channel() return CHANNEL_NONE; } - uint8_t SettingsBusTracking::next_free_xta_channel() { @@ -80,145 +76,137 @@ SettingsBusTracking::next_free_xta_channel() return CHANNEL_NONE; } - uint8_t SettingsBusTracking::next_free_ide_channel() { - int i, element; + int i, element; uint64_t mask; - uint8_t ret = CHANNEL_NONE; + uint8_t ret = CHANNEL_NONE; for (i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(ide_tracking[element] & mask)) { - ret = (uint8_t) i; - break; + ret = (uint8_t) i; + break; } } return ret; } - uint8_t SettingsBusTracking::next_free_scsi_id() { - int i, element; + int i, element; uint64_t mask; - uint8_t ret = CHANNEL_NONE; + uint8_t ret = CHANNEL_NONE; for (i = 0; i < 64; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (!(scsi_tracking[element] & mask)) { - ret = (uint8_t) i; - break; + ret = (uint8_t) i; + break; } } return ret; } - int SettingsBusTracking::mfm_bus_full() { - int i; + int i; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (mfm_tracking & mask) - count++; + count++; } return (count == 2); } - int SettingsBusTracking::esdi_bus_full() { - int i; + int i; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (esdi_tracking & mask) - count++; + count++; } return (count == 2); } - int SettingsBusTracking::xta_bus_full() { - int i; + int i; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 2; i++) { mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (xta_tracking & mask) - count++; + count++; } return (count == 2); } - int SettingsBusTracking::ide_bus_full() { - int i, element; + int i, element; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 32; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (ide_tracking[element] & mask) - count++; + count++; } return (count == 32); } - int SettingsBusTracking::scsi_bus_full() { - int i, element; + int i, element; uint64_t mask; - uint8_t count = 0; + uint8_t count = 0; for (i = 0; i < 64; i++) { element = ((i << 3) >> 6); - mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); + mask = 0xffULL << ((uint64_t) ((i << 3) & 0x3f)); if (scsi_tracking[element] & mask) - count++; + count++; } return (count == 64); } - void SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channel) { - int element; + int element; uint64_t mask; switch (bus) { @@ -252,7 +240,7 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe case HDD_BUS_IDE: case HDD_BUS_ATAPI: element = ((channel << 3) >> 6); - mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); if (set) ide_tracking[element] |= mask; @@ -262,7 +250,7 @@ SettingsBusTracking::device_track(int set, uint8_t dev_type, int bus, int channe case HDD_BUS_SCSI: element = ((channel << 3) >> 6); - mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); + mask = ((uint64_t) dev_type) << ((uint64_t) ((channel << 3) & 0x3f)); if (set) scsi_tracking[element] |= mask; diff --git a/src/qt/qt_settings_bus_tracking.hpp b/src/qt/qt_settings_bus_tracking.hpp index 0272b4359..fb878b716 100644 --- a/src/qt/qt_settings_bus_tracking.hpp +++ b/src/qt/qt_settings_bus_tracking.hpp @@ -3,28 +3,27 @@ #include -#define TRACK_CLEAR 0 -#define TRACK_SET 1 +#define TRACK_CLEAR 0 +#define TRACK_SET 1 -#define DEV_HDD 0x01 -#define DEV_CDROM 0x02 -#define DEV_ZIP 0x04 -#define DEV_MO 0x08 +#define DEV_HDD 0x01 +#define DEV_CDROM 0x02 +#define DEV_ZIP 0x04 +#define DEV_MO 0x08 -#define BUS_MFM 0 -#define BUS_ESDI 1 -#define BUS_XTA 2 -#define BUS_IDE 3 -#define BUS_SCSI 4 +#define BUS_MFM 0 +#define BUS_ESDI 1 +#define BUS_XTA 2 +#define BUS_IDE 3 +#define BUS_SCSI 4 -#define CHANNEL_NONE 0xff +#define CHANNEL_NONE 0xff namespace Ui { class SettingsBusTracking; } -class SettingsBusTracking -{ +class SettingsBusTracking { public: explicit SettingsBusTracking(); ~SettingsBusTracking() = default; @@ -49,15 +48,15 @@ public: private: /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t mfm_tracking{0}; + uint64_t mfm_tracking { 0 }; /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t esdi_tracking{0}; + uint64_t esdi_tracking { 0 }; /* 1 channel, 2 devices per channel, 8 bits per device = 16 bits. */ - uint64_t xta_tracking{0}; + uint64_t xta_tracking { 0 }; /* 16 channels (prepatation for that weird IDE card), 2 devices per channel, 8 bits per device = 256 bits. */ - uint64_t ide_tracking[4]{0, 0, 0, 0}; + uint64_t ide_tracking[4] { 0, 0, 0, 0 }; /* 4 buses, 16 devices per bus, 8 bits per device (future-proofing) = 512 bits. */ - uint64_t scsi_tracking[8]{0, 0, 0, 0, 0, 0, 0, 0}; + uint64_t scsi_tracking[8] { 0, 0, 0, 0, 0, 0, 0, 0 }; }; #endif // QT_SETTINGS_BUS_TRACKING_HPP diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index 84054806d..6ed9e7094 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -30,9 +30,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsDisplay::SettingsDisplay(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsDisplay) +SettingsDisplay::SettingsDisplay(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsDisplay) { ui->setupUi(this); @@ -44,22 +44,26 @@ SettingsDisplay::~SettingsDisplay() delete ui; } -void SettingsDisplay::save() { - gfxcard = ui->comboBoxVideo->currentData().toInt(); - gfxcard_2 = ui->comboBoxVideoSecondary->currentData().toInt(); - voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; +void +SettingsDisplay::save() +{ + gfxcard = ui->comboBoxVideo->currentData().toInt(); + gfxcard_2 = ui->comboBoxVideoSecondary->currentData().toInt(); + voodoo_enabled = ui->checkBoxVoodoo->isChecked() ? 1 : 0; ibm8514_enabled = ui->checkBox8514->isChecked() ? 1 : 0; - xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; + xga_enabled = ui->checkBoxXga->isChecked() ? 1 : 0; } -void SettingsDisplay::onCurrentMachineChanged(int machineId) { +void +SettingsDisplay::onCurrentMachineChanged(int machineId) +{ // win_settings_video_proc, WM_INITDIALOG this->machineId = machineId; - auto* model = ui->comboBoxVideo->model(); - auto removeRows = model->rowCount(); + auto *model = ui->comboBoxVideo->model(); + auto removeRows = model->rowCount(); - int c = 0; + int c = 0; int selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ @@ -68,14 +72,13 @@ void SettingsDisplay::onCurrentMachineChanged(int machineId) { continue; } - const device_t* video_dev = video_card_getdevice(c); - QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); + const device_t *video_dev = video_card_getdevice(c); + QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); if (name.isEmpty()) { break; } - if (video_card_available(c) && - device_is_valid(video_dev, machineId)) { + if (video_card_available(c) && device_is_valid(video_dev, machineId)) { int row = Models::AddEntry(model, name, c); if (c == gfxcard) { selectedRow = row - removeRows; @@ -97,27 +100,36 @@ void SettingsDisplay::onCurrentMachineChanged(int machineId) { ui->pushButtonConfigureSecondary->setEnabled(true); } ui->comboBoxVideo->setCurrentIndex(selectedRow); - if (gfxcard_2 == 0) ui->pushButtonConfigureSecondary->setEnabled(false); + if (gfxcard_2 == 0) + ui->pushButtonConfigureSecondary->setEnabled(false); } -void SettingsDisplay::on_pushButtonConfigure_clicked() { - auto* device = video_card_getdevice(ui->comboBoxVideo->currentData().toInt()); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); +void +SettingsDisplay::on_pushButtonConfigure_clicked() +{ + auto *device = video_card_getdevice(ui->comboBoxVideo->currentData().toInt()); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } -void SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() { - DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast(Settings::settings)); +void +SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() +{ + DeviceConfig::ConfigureDevice(&voodoo_device, 0, qobject_cast(Settings::settings)); } -void SettingsDisplay::on_pushButtonConfigureXga_clicked() { +void +SettingsDisplay::on_pushButtonConfigureXga_clicked() +{ if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { - DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); } else { - DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); } } -void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { +void +SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) +{ if (index < 0) { return; } @@ -132,7 +144,7 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { ui->pushButtonConfigureVoodoo->setEnabled(machineHasPci && ui->checkBoxVoodoo->isChecked()); bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; - bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; + bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; ui->checkBox8514->setEnabled(hasIsa16 || has_MCA); if (hasIsa16 || has_MCA) { ui->checkBox8514->setChecked(ibm8514_enabled); @@ -156,39 +168,41 @@ void SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) { return; } while (true) { - const device_t* video_dev = video_card_getdevice(c); - QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); + const device_t *video_dev = video_card_getdevice(c); + QString name = DeviceConfig::DeviceName(video_dev, video_get_internal_name(c), 1); if (name.isEmpty()) { break; } - if (video_card_available(c) && - device_is_valid(video_dev, machineId) && - !(video_card_get_flags(c) == video_card_get_flags(videoCard))) { - ui->comboBoxVideoSecondary->addItem(name, c); - if (c == gfxcard_2) - ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1); + if (video_card_available(c) && device_is_valid(video_dev, machineId) && !(video_card_get_flags(c) == video_card_get_flags(videoCard))) { + ui->comboBoxVideoSecondary->addItem(name, c); + if (c == gfxcard_2) + ui->comboBoxVideoSecondary->setCurrentIndex(ui->comboBoxVideoSecondary->count() - 1); } c++; } - if (gfxcard_2 == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) - { + if (gfxcard_2 == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { ui->comboBoxVideoSecondary->setCurrentIndex(0); ui->pushButtonConfigureSecondary->setEnabled(false); } } -void SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) { +void +SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) +{ ui->pushButtonConfigureVoodoo->setEnabled(state == Qt::Checked); } -void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { +void +SettingsDisplay::on_checkBoxXga_stateChanged(int state) +{ ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked); } -void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) +void +SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) { if (index < 0) { ui->pushButtonConfigureSecondary->setEnabled(false); @@ -198,10 +212,9 @@ void SettingsDisplay::on_comboBoxVideoSecondary_currentIndexChanged(int index) ui->pushButtonConfigureSecondary->setEnabled(index != 0 && video_card_has_config(videoCard) > 0); } - -void SettingsDisplay::on_pushButtonConfigureSecondary_clicked() +void +SettingsDisplay::on_pushButtonConfigureSecondary_clicked() { - auto* device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt()); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + auto *device = video_card_getdevice(ui->comboBoxVideoSecondary->currentData().toInt()); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } - diff --git a/src/qt/qt_settingsdisplay.hpp b/src/qt/qt_settingsdisplay.hpp index 06badd656..0aab5c161 100644 --- a/src/qt/qt_settingsdisplay.hpp +++ b/src/qt/qt_settingsdisplay.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsDisplay; } -class SettingsDisplay : public QWidget -{ +class SettingsDisplay : public QWidget { Q_OBJECT public: @@ -36,7 +35,7 @@ private slots: private: Ui::SettingsDisplay *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSDISPLAY_HPP diff --git a/src/qt/qt_settingsfloppycdrom.cpp b/src/qt/qt_settingsfloppycdrom.cpp index 32943f9a6..2eabe80ab 100644 --- a/src/qt/qt_settingsfloppycdrom.cpp +++ b/src/qt/qt_settingsfloppycdrom.cpp @@ -32,7 +32,9 @@ extern "C" { #include "qt_settings_bus_tracking.hpp" #include "qt_progsettings.hpp" -static void setFloppyType(QAbstractItemModel* model, const QModelIndex& idx, int type) { +static void +setFloppyType(QAbstractItemModel *model, const QModelIndex &idx, int type) +{ QIcon icon; if (type == 0) { icon = ProgSettings::loadIcon("/floppy_disabled.ico"); @@ -47,16 +49,18 @@ static void setFloppyType(QAbstractItemModel* model, const QModelIndex& idx, int model->setData(idx, icon, Qt::DecorationRole); } -static void setCDROMBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { +static void +setCDROMBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +{ QIcon icon; switch (bus) { - case CDROM_BUS_DISABLED: - icon = ProgSettings::loadIcon("/cdrom_disabled.ico"); - break; - case CDROM_BUS_ATAPI: - case CDROM_BUS_SCSI: - icon = ProgSettings::loadIcon("/cdrom.ico"); - break; + case CDROM_BUS_DISABLED: + icon = ProgSettings::loadIcon("/cdrom_disabled.ico"); + break; + case CDROM_BUS_ATAPI: + case CDROM_BUS_SCSI: + icon = ProgSettings::loadIcon("/cdrom.ico"); + break; } auto i = idx.siblingAtColumn(0); @@ -66,27 +70,32 @@ static void setCDROMBus(QAbstractItemModel* model, const QModelIndex& idx, uint8 model->setData(i, icon, Qt::DecorationRole); } -static void setCDROMSpeed(QAbstractItemModel* model, const QModelIndex& idx, uint8_t speed) { - if (!speed) speed = 8; +static void +setCDROMSpeed(QAbstractItemModel *model, const QModelIndex &idx, uint8_t speed) +{ + if (!speed) + speed = 8; auto i = idx.siblingAtColumn(1); model->setData(i, QString("%1x").arg(speed)); model->setData(i, speed, Qt::UserRole); } -static void setCDROMEarly(QAbstractItemModel* model, const QModelIndex& idx, bool early) { +static void +setCDROMEarly(QAbstractItemModel *model, const QModelIndex &idx, bool early) +{ auto i = idx.siblingAtColumn(2); model->setData(i, (early == true) ? QObject::tr("On") : QObject::tr("Off")); model->setData(i, early, Qt::UserRole); } -SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsFloppyCDROM) +SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsFloppyCDROM) { ui->setupUi(this); - auto* model = ui->comboBoxFloppyType->model(); - int i = 0; + auto *model = ui->comboBoxFloppyType->model(); + int i = 0; while (true) { QString name = tr(fdd_getname(i)); if (name.isEmpty()) { @@ -106,8 +115,8 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : model->insertRows(0, FDD_NUM); /* Floppy drives category */ for (int i = 0; i < FDD_NUM; i++) { - auto idx = model->index(i, 0); - int type = fdd_get_type(i); + auto idx = model->index(i, 0); + int type = fdd_get_type(i); setFloppyType(model, idx, type); model->setData(idx.siblingAtColumn(1), fdd_get_turbo(i) > 0 ? tr("On") : tr("Off")); model->setData(idx.siblingAtColumn(2), fdd_get_check_bpb(i) > 0 ? tr("On") : tr("Off")); @@ -119,7 +128,6 @@ SettingsFloppyCDROM::SettingsFloppyCDROM(QWidget *parent) : connect(ui->tableViewFloppy->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsFloppyCDROM::onFloppyRowChanged); ui->tableViewFloppy->setCurrentIndex(model->index(0, 0)); - Harddrives::populateRemovableBuses(ui->comboBoxBus->model()); model = ui->comboBoxSpeed->model(); for (int i = 0; i < 72; i++) { @@ -151,8 +159,10 @@ SettingsFloppyCDROM::~SettingsFloppyCDROM() delete ui; } -void SettingsFloppyCDROM::save() { - auto* model = ui->tableViewFloppy->model(); +void +SettingsFloppyCDROM::save() +{ + auto *model = ui->tableViewFloppy->model(); for (int i = 0; i < FDD_NUM; i++) { fdd_set_type(i, model->index(i, 0).data(Qt::UserRole).toInt()); fdd_set_turbo(i, model->index(i, 1).data() == tr("On") ? 1 : 0); @@ -162,44 +172,48 @@ void SettingsFloppyCDROM::save() { /* Removable devices category */ model = ui->tableViewCDROM->model(); for (int i = 0; i < CDROM_NUM; i++) { - cdrom[i].is_dir = 0; - cdrom[i].priv = NULL; - cdrom[i].ops = NULL; - cdrom[i].image = NULL; - cdrom[i].insert = NULL; - cdrom[i].close = NULL; - cdrom[i].get_volume = NULL; + cdrom[i].is_dir = 0; + cdrom[i].priv = NULL; + cdrom[i].ops = NULL; + cdrom[i].image = NULL; + cdrom[i].insert = NULL; + cdrom[i].close = NULL; + cdrom[i].get_volume = NULL; cdrom[i].get_channel = NULL; - cdrom[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); - cdrom[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); - cdrom[i].speed = model->index(i, 1).data(Qt::UserRole).toUInt(); - cdrom[i].early = model->index(i, 2).data(Qt::UserRole).toUInt(); + cdrom[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); + cdrom[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + cdrom[i].speed = model->index(i, 1).data(Qt::UserRole).toUInt(); + cdrom[i].early = model->index(i, 2).data(Qt::UserRole).toUInt(); } } -void SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex ¤t) { +void +SettingsFloppyCDROM::onFloppyRowChanged(const QModelIndex ¤t) +{ int type = current.siblingAtColumn(0).data(Qt::UserRole).toInt(); ui->comboBoxFloppyType->setCurrentIndex(type); ui->checkBoxTurboTimings->setChecked(current.siblingAtColumn(1).data() == tr("On")); ui->checkBoxCheckBPB->setChecked(current.siblingAtColumn(2).data() == tr("On")); } -void SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) { - uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); +void +SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) +{ + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); - bool early = current.siblingAtColumn(2).data(Qt::UserRole).toBool(); + uint8_t speed = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + bool early = current.siblingAtColumn(2).data(Qt::UserRole).toBool(); ui->comboBoxBus->setCurrentIndex(-1); - auto* model = ui->comboBoxBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxChannel->setCurrentIndex(match.first().row()); } @@ -207,26 +221,34 @@ void SettingsFloppyCDROM::onCDROMRowChanged(const QModelIndex ¤t) { ui->checkBoxEarlierDrive->setChecked(early); } -void SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1) { +void +SettingsFloppyCDROM::on_checkBoxTurboTimings_stateChanged(int arg1) +{ auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(1), arg1 == Qt::Checked ? tr("On") : tr("Off")); } -void SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1) { +void +SettingsFloppyCDROM::on_checkBoxCheckBPB_stateChanged(int arg1) +{ auto idx = ui->tableViewFloppy->selectionModel()->currentIndex(); ui->tableViewFloppy->model()->setData(idx.siblingAtColumn(2), arg1 == Qt::Checked ? tr("On") : tr("Off")); } -void SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) { +void +SettingsFloppyCDROM::on_comboBoxFloppyType_activated(int index) +{ setFloppyType(ui->tableViewFloppy->model(), ui->tableViewFloppy->selectionModel()->currentIndex(), index); } -void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { +void +SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) +{ if (index < 0) { return; } - int bus = ui->comboBoxBus->currentData().toInt(); + int bus = ui->comboBoxBus->currentData().toInt(); bool enabled = (bus != CDROM_BUS_DISABLED); ui->comboBoxChannel->setEnabled(enabled); ui->comboBoxSpeed->setEnabled(enabled); @@ -234,13 +256,16 @@ void SettingsFloppyCDROM::on_comboBoxBus_currentIndexChanged(int index) { Harddrives::populateBusChannels(ui->comboBoxChannel->model(), bus); } -void SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) { +void +SettingsFloppyCDROM::on_comboBoxSpeed_activated(int index) +{ auto idx = ui->tableViewCDROM->selectionModel()->currentIndex(); setCDROMSpeed(ui->tableViewCDROM->model(), idx.siblingAtColumn(1), index + 1); } - -void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { +void +SettingsFloppyCDROM::on_comboBoxBus_activated(int) +{ auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); ui->comboBoxChannel->setCurrentIndex(ui->comboBoxBus->currentData().toUInt() == CDROM_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); @@ -252,8 +277,9 @@ void SettingsFloppyCDROM::on_comboBoxBus_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); } - -void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { +void +SettingsFloppyCDROM::on_comboBoxChannel_activated(int) +{ auto i = ui->tableViewCDROM->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); setCDROMBus( @@ -264,9 +290,9 @@ void SettingsFloppyCDROM::on_comboBoxChannel_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_CDROM, ui->tableViewCDROM->model()->data(i, Qt::UserRole).toInt(), ui->tableViewCDROM->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsFloppyCDROM::on_checkBoxEarlierDrive_stateChanged(int arg1) +void +SettingsFloppyCDROM::on_checkBoxEarlierDrive_stateChanged(int arg1) { auto idx = ui->tableViewCDROM->selectionModel()->currentIndex(); setCDROMEarly(ui->tableViewCDROM->model(), idx.siblingAtColumn(2), (arg1 == Qt::Checked) ? true : false); } - diff --git a/src/qt/qt_settingsfloppycdrom.hpp b/src/qt/qt_settingsfloppycdrom.hpp index 4f50031cf..5c2920199 100644 --- a/src/qt/qt_settingsfloppycdrom.hpp +++ b/src/qt/qt_settingsfloppycdrom.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsFloppyCDROM; } -class SettingsFloppyCDROM : public QWidget -{ +class SettingsFloppyCDROM : public QWidget { Q_OBJECT public: diff --git a/src/qt/qt_settingsharddisks.cpp b/src/qt/qt_settingsharddisks.cpp index 0c3938c91..1883797e5 100644 --- a/src/qt/qt_settingsharddisks.cpp +++ b/src/qt/qt_settingsharddisks.cpp @@ -31,18 +31,18 @@ extern "C" { #include "qt_settings_bus_tracking.hpp" #include "qt_progsettings.hpp" -const int ColumnBus = 0; -const int ColumnFilename = 1; -const int ColumnCylinders = 2; -const int ColumnHeads = 3; -const int ColumnSectors = 4; -const int ColumnSize = 5; -const int ColumnSpeed = 6; +const int ColumnBus = 0; +const int ColumnFilename = 1; +const int ColumnCylinders = 2; +const int ColumnHeads = 3; +const int ColumnSectors = 4; +const int ColumnSize = 5; +const int ColumnSpeed = 6; -const int DataBus = Qt::UserRole; -const int DataBusChannel = Qt::UserRole + 1; -const int DataBusPrevious = Qt::UserRole + 2; -const int DataBusChannelPrevious = Qt::UserRole + 3; +const int DataBus = Qt::UserRole; +const int DataBusChannel = Qt::UserRole + 1; +const int DataBusPrevious = Qt::UserRole + 2; +const int DataBusChannelPrevious = Qt::UserRole + 3; /* static void @@ -65,11 +65,15 @@ normalize_hd_list() } */ -static QString busChannelName(const QModelIndex& idx) { +static QString +busChannelName(const QModelIndex &idx) +{ return Harddrives::BusChannelName(idx.data(DataBus).toUInt(), idx.data(DataBusChannel).toUInt()); } -static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { +static void +addRow(QAbstractItemModel *model, hard_disk_t *hd) +{ const QString userPath = usr_path; int row = model->rowCount(); @@ -77,7 +81,7 @@ static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { QString busName = Harddrives::BusChannelName(hd->bus, hd->channel); model->setData(model->index(row, ColumnBus), busName); - model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon( "/hard_disk.ico"), Qt::DecorationRole); + model->setData(model->index(row, ColumnBus), ProgSettings::loadIcon("/hard_disk.ico"), Qt::DecorationRole); model->setData(model->index(row, ColumnBus), hd->bus, DataBus); model->setData(model->index(row, ColumnBus), hd->bus, DataBusPrevious); model->setData(model->index(row, ColumnBus), hd->channel, DataBusChannel); @@ -99,13 +103,13 @@ static void addRow(QAbstractItemModel* model, hard_disk_t* hd) { model->setData(model->index(row, ColumnSpeed), hd->speed_preset, Qt::UserRole); } -SettingsHarddisks::SettingsHarddisks(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsHarddisks) +SettingsHarddisks::SettingsHarddisks(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsHarddisks) { ui->setupUi(this); - QAbstractItemModel* model = new QStandardItemModel(0, 7, this); + QAbstractItemModel *model = new QStandardItemModel(0, 7, this); model->setHeaderData(ColumnBus, Qt::Horizontal, tr("Bus")); model->setHeaderData(ColumnFilename, Qt::Horizontal, tr("File")); model->setHeaderData(ColumnCylinders, Qt::Horizontal, tr("C")); @@ -120,15 +124,14 @@ SettingsHarddisks::SettingsHarddisks(QWidget *parent) : addRow(model, &hdd[i]); } } - if (model->rowCount() == HDD_NUM) - { + if (model->rowCount() == HDD_NUM) { ui->pushButtonNew->setEnabled(false); ui->pushButtonExisting->setEnabled(false); } ui->tableView->resizeColumnsToContents(); ui->tableView->horizontalHeader()->setSectionResizeMode(ColumnFilename, QHeaderView::Stretch); - auto* tableSelectionModel = ui->tableView->selectionModel(); + auto *tableSelectionModel = ui->tableView->selectionModel(); connect(tableSelectionModel, &QItemSelectionModel::currentRowChanged, this, &SettingsHarddisks::onTableRowChanged); onTableRowChanged(QModelIndex()); @@ -141,18 +144,20 @@ SettingsHarddisks::~SettingsHarddisks() delete ui; } -void SettingsHarddisks::save() { +void +SettingsHarddisks::save() +{ memset(hdd, 0, sizeof(hdd)); - auto* model = ui->tableView->model(); - int rows = model->rowCount(); + auto *model = ui->tableView->model(); + int rows = model->rowCount(); for (int i = 0; i < rows; ++i) { - auto idx = model->index(i, ColumnBus); - hdd[i].bus = idx.data(DataBus).toUInt(); - hdd[i].channel = idx.data(DataBusChannel).toUInt(); - hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt(); - hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt(); - hdd[i].spt = idx.siblingAtColumn(ColumnSectors).data().toUInt(); + auto idx = model->index(i, ColumnBus); + hdd[i].bus = idx.data(DataBus).toUInt(); + hdd[i].channel = idx.data(DataBusChannel).toUInt(); + hdd[i].tracks = idx.siblingAtColumn(ColumnCylinders).data().toUInt(); + hdd[i].hpc = idx.siblingAtColumn(ColumnHeads).data().toUInt(); + hdd[i].spt = idx.siblingAtColumn(ColumnSectors).data().toUInt(); hdd[i].speed_preset = idx.siblingAtColumn(ColumnSpeed).data(Qt::UserRole).toUInt(); QByteArray fileName = idx.siblingAtColumn(ColumnFilename).data(Qt::UserRole).toString().toUtf8(); @@ -161,16 +166,18 @@ void SettingsHarddisks::save() { } } -void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { +void +SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) +{ if (index < 0) { return; } buschangeinprogress = true; - auto idx = ui->tableView->selectionModel()->currentIndex(); + auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); model->setData(col, ui->comboBoxBus->currentData(Qt::UserRole), DataBus); model->setData(col, busChannelName(col), Qt::DisplayRole); Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBusPrevious).toInt(), model->data(col, DataBusChannelPrevious).toInt()); @@ -181,8 +188,7 @@ void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { Harddrives::populateSpeeds(ui->comboBoxSpeed->model(), ui->comboBoxBus->currentData().toInt()); int chanIdx = 0; - switch (ui->comboBoxBus->currentData().toInt()) - { + switch (ui->comboBoxBus->currentData().toInt()) { case HDD_BUS_MFM: chanIdx = (Harddrives::busTrackClass->next_free_mfm_channel()); break; @@ -202,46 +208,53 @@ void SettingsHarddisks::on_comboBoxBus_currentIndexChanged(int index) { } if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); model->setData(col, chanIdx, DataBusChannelPrevious); } ui->comboBoxChannel->setCurrentIndex(chanIdx); buschangeinprogress = false; } -void SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) { +void +SettingsHarddisks::on_comboBoxChannel_currentIndexChanged(int index) +{ if (index < 0) { return; } auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnBus); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnBus); model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannel); model->setData(col, busChannelName(col), Qt::DisplayRole); - if (!buschangeinprogress) Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); + if (!buschangeinprogress) + Harddrives::busTrackClass->device_track(0, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannelPrevious).toUInt()); Harddrives::busTrackClass->device_track(1, DEV_HDD, model->data(col, DataBus).toInt(), model->data(col, DataBusChannel).toUInt()); model->setData(col, ui->comboBoxChannel->currentData(Qt::UserRole), DataBusChannelPrevious); } } -void SettingsHarddisks::on_comboBoxSpeed_currentIndexChanged(int index) { +void +SettingsHarddisks::on_comboBoxSpeed_currentIndexChanged(int index) +{ if (index < 0) { return; } auto idx = ui->tableView->selectionModel()->currentIndex(); if (idx.isValid()) { - auto* model = ui->tableView->model(); - auto col = idx.siblingAtColumn(ColumnSpeed); + auto *model = ui->tableView->model(); + auto col = idx.siblingAtColumn(ColumnSpeed); model->setData(col, ui->comboBoxSpeed->currentData(Qt::UserRole), Qt::UserRole); model->setData(col, hdd_preset_getname(ui->comboBoxSpeed->currentData(Qt::UserRole).toUInt())); } } -void SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) { +void +SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) +{ bool hidden = !current.isValid(); ui->labelBus->setHidden(hidden); ui->labelChannel->setHidden(hidden); @@ -250,78 +263,84 @@ void SettingsHarddisks::onTableRowChanged(const QModelIndex ¤t) { ui->comboBoxChannel->setHidden(hidden); ui->comboBoxSpeed->setHidden(hidden); - uint32_t bus = current.siblingAtColumn(ColumnBus).data(DataBus).toUInt(); + uint32_t bus = current.siblingAtColumn(ColumnBus).data(DataBus).toUInt(); uint32_t busChannel = current.siblingAtColumn(ColumnBus).data(DataBusChannel).toUInt(); - uint32_t speed = current.siblingAtColumn(ColumnSpeed).data(Qt::UserRole).toUInt(); + uint32_t speed = current.siblingAtColumn(ColumnSpeed).data(Qt::UserRole).toUInt(); - auto* model = ui->comboBoxBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, busChannel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxChannel->setCurrentIndex(match.first().row()); } model = ui->comboBoxSpeed->model(); match = model->match(model->index(0, 0), Qt::UserRole, speed); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxSpeed->setCurrentIndex(match.first().row()); } } -static void addDriveFromDialog(Ui::SettingsHarddisks* ui, const HarddiskDialog& dlg) { +static void +addDriveFromDialog(Ui::SettingsHarddisks *ui, const HarddiskDialog &dlg) +{ QByteArray fn = dlg.fileName().toUtf8(); hard_disk_t hd; memset(&hd, 0, sizeof(hd)); - hd.bus = dlg.bus(); + hd.bus = dlg.bus(); hd.channel = dlg.channel(); - hd.tracks = dlg.cylinders(); - hd.hpc = dlg.heads(); - hd.spt = dlg.sectors(); + hd.tracks = dlg.cylinders(); + hd.hpc = dlg.heads(); + hd.spt = dlg.sectors(); strncpy(hd.fn, fn.data(), sizeof(hd.fn) - 1); hd.speed_preset = dlg.speed(); addRow(ui->tableView->model(), &hd); ui->tableView->resizeColumnsToContents(); ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch); - if (ui->tableView->model()->rowCount() == HDD_NUM) - { + if (ui->tableView->model()->rowCount() == HDD_NUM) { ui->pushButtonNew->setEnabled(false); ui->pushButtonExisting->setEnabled(false); } } -void SettingsHarddisks::on_pushButtonNew_clicked() { +void +SettingsHarddisks::on_pushButtonNew_clicked() +{ HarddiskDialog dialog(false, this); switch (dialog.exec()) { - case QDialog::Accepted: - addDriveFromDialog(ui, dialog); - break; + case QDialog::Accepted: + addDriveFromDialog(ui, dialog); + break; } } - -void SettingsHarddisks::on_pushButtonExisting_clicked() { +void +SettingsHarddisks::on_pushButtonExisting_clicked() +{ HarddiskDialog dialog(true, this); switch (dialog.exec()) { - case QDialog::Accepted: - addDriveFromDialog(ui, dialog); - break; + case QDialog::Accepted: + addDriveFromDialog(ui, dialog); + break; } } -void SettingsHarddisks::on_pushButtonRemove_clicked() { +void +SettingsHarddisks::on_pushButtonRemove_clicked() +{ auto idx = ui->tableView->selectionModel()->currentIndex(); - if (! idx.isValid()) { + if (!idx.isValid()) { return; } - auto* model = ui->tableView->model(); + auto *model = ui->tableView->model(); model->removeRow(idx.row()); ui->pushButtonNew->setEnabled(true); ui->pushButtonExisting->setEnabled(true); diff --git a/src/qt/qt_settingsharddisks.hpp b/src/qt/qt_settingsharddisks.hpp index a8aebb0bd..68d7ca3d6 100644 --- a/src/qt/qt_settingsharddisks.hpp +++ b/src/qt/qt_settingsharddisks.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsHarddisks; } -class SettingsHarddisks : public QWidget -{ +class SettingsHarddisks : public QWidget { Q_OBJECT public: @@ -27,11 +26,11 @@ private slots: void on_pushButtonNew_clicked(); void on_comboBoxBus_currentIndexChanged(int index); - void onTableRowChanged(const QModelIndex& current); + void onTableRowChanged(const QModelIndex ¤t); private: Ui::SettingsHarddisks *ui; - bool buschangeinprogress = false; + bool buschangeinprogress = false; }; #endif // QT_SETTINGSHARDDISKS_HPP diff --git a/src/qt/qt_settingsinput.cpp b/src/qt/qt_settingsinput.cpp index d5a62534f..49d84037f 100644 --- a/src/qt/qt_settingsinput.cpp +++ b/src/qt/qt_settingsinput.cpp @@ -31,9 +31,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_joystickconfiguration.hpp" -SettingsInput::SettingsInput(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsInput) +SettingsInput::SettingsInput(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsInput) { ui->setupUi(this); @@ -45,21 +45,25 @@ SettingsInput::~SettingsInput() delete ui; } -void SettingsInput::save() { - mouse_type = ui->comboBoxMouse->currentData().toInt(); +void +SettingsInput::save() +{ + mouse_type = ui->comboBoxMouse->currentData().toInt(); joystick_type = ui->comboBoxJoystick->currentData().toInt(); } -void SettingsInput::onCurrentMachineChanged(int machineId) { +void +SettingsInput::onCurrentMachineChanged(int machineId) +{ // win_settings_video_proc, WM_INITDIALOG this->machineId = machineId; - auto* mouseModel = ui->comboBoxMouse->model(); - auto removeRows = mouseModel->rowCount(); + auto *mouseModel = ui->comboBoxMouse->model(); + auto removeRows = mouseModel->rowCount(); int selectedRow = 0; for (int i = 0; i < mouse_get_ndev(); ++i) { - const auto* dev = mouse_get_device(i); + const auto *dev = mouse_get_device(i); if ((i == MOUSE_TYPE_INTERNAL) && (machine_has_flags(machineId, MACHINE_MOUSE) == 0)) { continue; } @@ -69,7 +73,7 @@ void SettingsInput::onCurrentMachineChanged(int machineId) { } QString name = DeviceConfig::DeviceName(dev, mouse_get_internal_name(i), 0); - int row = mouseModel->rowCount(); + int row = mouseModel->rowCount(); mouseModel->insertRow(row); auto idx = mouseModel->index(row, 0); @@ -83,12 +87,11 @@ void SettingsInput::onCurrentMachineChanged(int machineId) { mouseModel->removeRows(0, removeRows); ui->comboBoxMouse->setCurrentIndex(selectedRow); - - int i = 0; - char* joyName = joystick_get_name(i); - auto* joystickModel = ui->comboBoxJoystick->model(); - removeRows = joystickModel->rowCount(); - selectedRow = 0; + int i = 0; + char *joyName = joystick_get_name(i); + auto *joystickModel = ui->comboBoxJoystick->model(); + removeRows = joystickModel->rowCount(); + selectedRow = 0; while (joyName) { int row = Models::AddEntry(joystickModel, tr(joyName).toUtf8().data(), i); if (i == joystick_type) { @@ -102,16 +105,19 @@ void SettingsInput::onCurrentMachineChanged(int machineId) { ui->comboBoxJoystick->setCurrentIndex(selectedRow); } -void SettingsInput::on_comboBoxMouse_currentIndexChanged(int index) { +void +SettingsInput::on_comboBoxMouse_currentIndexChanged(int index) +{ int mouseId = ui->comboBoxMouse->currentData().toInt(); ui->pushButtonConfigureMouse->setEnabled(mouse_has_config(mouseId) > 0); } - -void SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) { +void +SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) +{ int joystickId = ui->comboBoxJoystick->currentData().toInt(); for (int i = 0; i < 4; ++i) { - auto* btn = findChild(QString("pushButtonJoystick%1").arg(i+1)); + auto *btn = findChild(QString("pushButtonJoystick%1").arg(i + 1)); if (btn == nullptr) { continue; } @@ -119,15 +125,19 @@ void SettingsInput::on_comboBoxJoystick_currentIndexChanged(int index) { } } -void SettingsInput::on_pushButtonConfigureMouse_clicked() { +void +SettingsInput::on_pushButtonConfigureMouse_clicked() +{ int mouseId = ui->comboBoxMouse->currentData().toInt(); - DeviceConfig::ConfigureDevice(mouse_get_device(mouseId), 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(mouse_get_device(mouseId), 0, qobject_cast(Settings::settings)); } -static int get_axis(JoystickConfiguration& jc, int axis, int joystick_nr) { +static int +get_axis(JoystickConfiguration &jc, int axis, int joystick_nr) +{ int axis_sel = jc.selectedAxis(axis); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; + int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_axes; + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs; if (axis_sel < nr_axes) { return axis_sel; @@ -145,12 +155,13 @@ static int get_axis(JoystickConfiguration& jc, int axis, int joystick_nr) { return SLIDER | (axis_sel >> 1); } -static int get_pov(JoystickConfiguration& jc, int pov, int joystick_nr) { +static int +get_pov(JoystickConfiguration &jc, int pov, int joystick_nr) +{ int pov_sel = jc.selectedPov(pov); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2; + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs * 2; - if (pov_sel < nr_povs) - { + if (pov_sel < nr_povs) { if (pov_sel & 1) return POV_Y | (pov_sel >> 1); else @@ -160,13 +171,15 @@ static int get_pov(JoystickConfiguration& jc, int pov, int joystick_nr) { return pov_sel - nr_povs; } -static void updateJoystickConfig(int type, int joystick_nr, QWidget* parent) { +static void +updateJoystickConfig(int type, int joystick_nr, QWidget *parent) +{ JoystickConfiguration jc(type, joystick_nr, parent); switch (jc.exec()) { - case QDialog::Rejected: - return; - case QDialog::Accepted: - break; + case QDialog::Rejected: + return; + case QDialog::Accepted: + break; } joystick_state[joystick_nr].plat_joystick_nr = jc.selectedDevice(); @@ -184,18 +197,26 @@ static void updateJoystickConfig(int type, int joystick_nr, QWidget* parent) { } } -void SettingsInput::on_pushButtonJoystick1_clicked() { +void +SettingsInput::on_pushButtonJoystick1_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 0, this); } -void SettingsInput::on_pushButtonJoystick2_clicked() { +void +SettingsInput::on_pushButtonJoystick2_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 1, this); } -void SettingsInput::on_pushButtonJoystick3_clicked() { +void +SettingsInput::on_pushButtonJoystick3_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 2, this); } -void SettingsInput::on_pushButtonJoystick4_clicked() { +void +SettingsInput::on_pushButtonJoystick4_clicked() +{ updateJoystickConfig(ui->comboBoxJoystick->currentData().toInt(), 3, this); } diff --git a/src/qt/qt_settingsinput.hpp b/src/qt/qt_settingsinput.hpp index f9e44740d..0b8b665aa 100644 --- a/src/qt/qt_settingsinput.hpp +++ b/src/qt/qt_settingsinput.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsInput; } -class SettingsInput : public QWidget -{ +class SettingsInput : public QWidget { Q_OBJECT public: @@ -31,7 +30,7 @@ private slots: private: Ui::SettingsInput *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSINPUT_HPP diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 56456000b..0d2ffa129 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -35,45 +35,45 @@ extern "C" { } // from nvr.h, which we can't import into CPP code -#define TIME_SYNC_DISABLED 0 -#define TIME_SYNC_ENABLED 1 -#define TIME_SYNC_UTC 2 +#define TIME_SYNC_DISABLED 0 +#define TIME_SYNC_ENABLED 1 +#define TIME_SYNC_UTC 2 #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsMachine::SettingsMachine(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsMachine) +SettingsMachine::SettingsMachine(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsMachine) { ui->setupUi(this); switch (time_sync) { - case TIME_SYNC_ENABLED: - ui->radioButtonLocalTime->setChecked(true); - break; - case TIME_SYNC_ENABLED | TIME_SYNC_UTC: - ui->radioButtonUTC->setChecked(true); - break; - case TIME_SYNC_DISABLED: - default: - ui->radioButtonDisabled->setChecked(true); - break; + case TIME_SYNC_ENABLED: + ui->radioButtonLocalTime->setChecked(true); + break; + case TIME_SYNC_ENABLED | TIME_SYNC_UTC: + ui->radioButtonUTC->setChecked(true); + break; + case TIME_SYNC_DISABLED: + default: + ui->radioButtonDisabled->setChecked(true); + break; } - auto* waitStatesModel = ui->comboBoxWaitStates->model(); + auto *waitStatesModel = ui->comboBoxWaitStates->model(); waitStatesModel->insertRows(0, 9); auto idx = waitStatesModel->index(0, 0); waitStatesModel->setData(idx, tr("Default"), Qt::DisplayRole); waitStatesModel->setData(idx, 0, Qt::UserRole); for (int i = 0; i < 8; ++i) { - idx = waitStatesModel->index(i+1, 0); + idx = waitStatesModel->index(i + 1, 0); waitStatesModel->setData(idx, QString::asprintf(tr("%i Wait state(s)").toUtf8().constData(), i), Qt::DisplayRole); - waitStatesModel->setData(idx, i+1, Qt::UserRole); + waitStatesModel->setData(idx, i + 1, Qt::UserRole); } - int selectedMachineType = 0; - auto* machineTypesModel = ui->comboBoxMachineType->model(); + int selectedMachineType = 0; + auto *machineTypesModel = ui->comboBoxMachineType->model(); for (int i = 1; i < MACHINE_TYPE_MAX; ++i) { int j = 0; while (machine_get_internal_name_ex(j) != nullptr) { @@ -92,15 +92,18 @@ SettingsMachine::SettingsMachine(QWidget *parent) : ui->comboBoxMachineType->setCurrentIndex(selectedMachineType); } -SettingsMachine::~SettingsMachine() { +SettingsMachine::~SettingsMachine() +{ delete ui; } -void SettingsMachine::save() { - machine = ui->comboBoxMachine->currentData().toInt(); - cpu_f = const_cast(&cpu_families[ui->comboBoxCPU->currentData().toInt()]); - cpu = ui->comboBoxSpeed->currentData().toInt(); - fpu_type = ui->comboBoxFPU->currentData().toInt(); +void +SettingsMachine::save() +{ + machine = ui->comboBoxMachine->currentData().toInt(); + cpu_f = const_cast(&cpu_families[ui->comboBoxCPU->currentData().toInt()]); + cpu = ui->comboBoxSpeed->currentData().toInt(); + fpu_type = ui->comboBoxFPU->currentData().toInt(); cpu_use_dynarec = ui->checkBoxDynamicRecompiler->isChecked() ? 1 : 0; int64_t temp_mem_size; if (machine_get_ram_granularity(machine) < 1024) { @@ -132,13 +135,15 @@ void SettingsMachine::save() { } } -void SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) +{ if (index < 0) { return; } - auto* model = ui->comboBoxMachine->model(); - int removeRows = model->rowCount(); + auto *model = ui->comboBoxMachine->model(); + int removeRows = model->rowCount(); int selectedMachineRow = 0; for (int i = 0; i < machine_count(); ++i) { @@ -155,22 +160,23 @@ void SettingsMachine::on_comboBoxMachineType_currentIndexChanged(int index) { ui->comboBoxMachine->setCurrentIndex(selectedMachineRow); } - -void SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) +{ // win_settings_machine_recalc_machine if (index < 0) { return; } - int machineId = ui->comboBoxMachine->currentData().toInt(); - const auto* device = machine_getdevice(machineId); + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto *device = machine_getdevice(machineId); ui->pushButtonConfigure->setEnabled((device != nullptr) && (device->config != nullptr)); - auto* modelCpu = ui->comboBoxCPU->model(); - int removeRows = modelCpu->rowCount(); + auto *modelCpu = ui->comboBoxCPU->model(); + int removeRows = modelCpu->rowCount(); - int i = 0; - int eligibleRows = 0; + int i = 0; + int eligibleRows = 0; int selectedCpuFamilyRow = 0; while (cpu_families[i].package != 0) { if (cpu_family_is_eligible(&cpu_families[i], machineId)) { @@ -204,22 +210,23 @@ void SettingsMachine::on_comboBoxMachine_currentIndexChanged(int index) { emit currentMachineChanged(machineId); } - -void SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) +{ if (index < 0) { return; } - int machineId = ui->comboBoxMachine->currentData().toInt(); - int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); - const auto* cpuFamily = &cpu_families[cpuFamilyId]; + int machineId = ui->comboBoxMachine->currentData().toInt(); + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; - auto* modelSpeed = ui->comboBoxSpeed->model(); - int removeRows = modelSpeed->rowCount(); + auto *modelSpeed = ui->comboBoxSpeed->model(); + int removeRows = modelSpeed->rowCount(); // win_settings_machine_recalc_cpu_m - int i = 0; - int eligibleRows = 0; + int i = 0; + int eligibleRows = 0; int selectedSpeedRow = 0; while (cpuFamily->cpus[i].cpu_type != 0) { if (cpu_is_eligible(cpuFamily, i, machineId)) { @@ -237,17 +244,18 @@ void SettingsMachine::on_comboBoxCPU_currentIndexChanged(int index) { ui->comboBoxSpeed->setCurrentIndex(selectedSpeedRow); } - -void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { +void +SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) +{ if (index < 0) { return; } // win_settings_machine_recalc_cpu - int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); - const auto* cpuFamily = &cpu_families[cpuFamilyId]; - int cpuId = ui->comboBoxSpeed->currentData().toInt(); - uint cpuType = cpuFamily->cpus[cpuId].cpu_type; + int cpuFamilyId = ui->comboBoxCPU->currentData().toInt(); + const auto *cpuFamily = &cpu_families[cpuFamilyId]; + int cpuId = ui->comboBoxSpeed->currentData().toInt(); + uint cpuType = cpuFamily->cpus[cpuId].cpu_type; if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { ui->comboBoxWaitStates->setEnabled(true); @@ -259,7 +267,7 @@ void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { #ifdef USE_DYNAREC uint8_t flags = cpuFamily->cpus[cpuId].cpu_flags; - if (! (flags & CPU_SUPPORTS_DYNAREC)) { + if (!(flags & CPU_SUPPORTS_DYNAREC)) { ui->checkBoxDynamicRecompiler->setChecked(false); ui->checkBoxDynamicRecompiler->setEnabled(false); } else if (flags & CPU_REQUIRES_DYNAREC) { @@ -272,12 +280,12 @@ void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { #endif // win_settings_machine_recalc_fpu - auto* modelFpu = ui->comboBoxFPU->model(); - int removeRows = modelFpu->rowCount(); + auto *modelFpu = ui->comboBoxFPU->model(); + int removeRows = modelFpu->rowCount(); - int i = 0; + int i = 0; int selectedFpuRow = 0; - for (const char* fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { + for (const char *fpuName = fpu_get_name_from_index(cpuFamily, cpuId, i); fpuName != nullptr; fpuName = fpu_get_name_from_index(cpuFamily, cpuId, ++i)) { auto fpuType = fpu_get_type_from_index(cpuFamily, cpuId, i); Models::AddEntry(modelFpu, QString("%1").arg(fpuName), fpuType); if (fpu_type == fpuType) { @@ -291,9 +299,11 @@ void SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) { ui->comboBoxFPU->setCurrentIndex(selectedFpuRow); } -void SettingsMachine::on_pushButtonConfigure_clicked() { +void +SettingsMachine::on_pushButtonConfigure_clicked() +{ // deviceconfig_inst_open - int machineId = ui->comboBoxMachine->currentData().toInt(); - const auto* device = machine_getdevice(machineId); - DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); + int machineId = ui->comboBoxMachine->currentData().toInt(); + const auto *device = machine_getdevice(machineId); + DeviceConfig::ConfigureDevice(device, 0, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsmachine.hpp b/src/qt/qt_settingsmachine.hpp index d0d4aabd2..abb4f3014 100644 --- a/src/qt/qt_settingsmachine.hpp +++ b/src/qt/qt_settingsmachine.hpp @@ -7,18 +7,17 @@ namespace Ui { class SettingsMachine; } -class SettingsMachine : public QWidget -{ +class SettingsMachine : public QWidget { Q_OBJECT public: - explicit SettingsMachine(QWidget *parent = nullptr); + explicit SettingsMachine(QWidget *parent = nullptr); ~SettingsMachine(); - void save(); + void save(); signals: - void currentMachineChanged(int machineId); + void currentMachineChanged(int machineId); private slots: void on_pushButtonConfigure_clicked(); @@ -32,7 +31,7 @@ private slots: void on_comboBoxMachine_currentIndexChanged(int index); private slots: - void on_comboBoxMachineType_currentIndexChanged(int index); + void on_comboBoxMachineType_currentIndexChanged(int index); private: Ui::SettingsMachine *ui; diff --git a/src/qt/qt_settingsnetwork.cpp b/src/qt/qt_settingsnetwork.cpp index 1cb42cc22..cbddfab72 100644 --- a/src/qt/qt_settingsnetwork.cpp +++ b/src/qt/qt_settingsnetwork.cpp @@ -29,16 +29,17 @@ extern "C" { #include "qt_models_common.hpp" #include "qt_deviceconfig.hpp" -void SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) { +void +SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) +{ for (int i = 0; i < NET_CARD_MAX; ++i) { - auto* nic_cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); - auto* net_type_cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - auto* intf_cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); - auto* conf_btn = findChild(QString("pushButtonConf%1").arg(i+1)); + auto *nic_cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *net_type_cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); + auto *conf_btn = findChild(QString("pushButtonConf%1").arg(i + 1)); - int netType = net_type_cbox->currentData().toInt(); - bool adaptersEnabled = netType == NET_TYPE_SLIRP || - (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0); + int netType = net_type_cbox->currentData().toInt(); + bool adaptersEnabled = netType == NET_TYPE_SLIRP || (netType == NET_TYPE_PCAP && intf_cbox->currentData().toInt() > 0); intf_cbox->setEnabled(net_type_cbox->currentData().toInt() == NET_TYPE_PCAP); nic_cbox->setEnabled(adaptersEnabled); @@ -46,18 +47,18 @@ void SettingsNetwork::enableElements(Ui::SettingsNetwork *ui) { } } -SettingsNetwork::SettingsNetwork(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsNetwork) +SettingsNetwork::SettingsNetwork(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsNetwork) { ui->setupUi(this); onCurrentMachineChanged(machine); enableElements(ui); for (int i = 0; i < NET_CARD_MAX; i++) { - auto* nic_cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); - auto* net_type_cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - auto* intf_cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); + auto *nic_cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *net_type_cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + auto *intf_cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); connect(nic_cbox, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged); connect(net_type_cbox, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged); connect(intf_cbox, QOverload::of(&QComboBox::currentIndexChanged), this, &SettingsNetwork::on_comboIndexChanged); @@ -69,30 +70,34 @@ SettingsNetwork::~SettingsNetwork() delete ui; } -void SettingsNetwork::save() { +void +SettingsNetwork::save() +{ for (int i = 0; i < NET_CARD_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); + auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); net_cards_conf[i].device_num = cbox->currentData().toInt(); - cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - net_cards_conf[i].net_type = cbox->currentData().toInt(); - cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); + cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + net_cards_conf[i].net_type = cbox->currentData().toInt(); + cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); memset(net_cards_conf[i].host_dev_name, '\0', sizeof(net_cards_conf[i].host_dev_name)); strncpy(net_cards_conf[i].host_dev_name, network_devs[cbox->currentData().toInt()].device, sizeof(net_cards_conf[i].host_dev_name) - 1); } } -void SettingsNetwork::onCurrentMachineChanged(int machineId) { +void +SettingsNetwork::onCurrentMachineChanged(int machineId) +{ this->machineId = machineId; - int c = 0; + int c = 0; int selectedRow = 0; for (int i = 0; i < NET_CARD_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxNIC%1").arg(i+1)); - auto *model = cbox->model(); - auto removeRows = model->rowCount(); - c = 0; - selectedRow = 0; + auto *cbox = findChild(QString("comboBoxNIC%1").arg(i + 1)); + auto *model = cbox->model(); + auto removeRows = model->rowCount(); + c = 0; + selectedRow = 0; while (true) { auto name = DeviceConfig::DeviceName(network_card_getdevice(c), network_card_get_internal_name(c), 1); @@ -114,8 +119,8 @@ void SettingsNetwork::onCurrentMachineChanged(int machineId) { cbox->setCurrentIndex(-1); cbox->setCurrentIndex(selectedRow); - cbox = findChild(QString("comboBoxNet%1").arg(i+1)); - model = cbox->model(); + cbox = findChild(QString("comboBoxNet%1").arg(i + 1)); + model = cbox->model(); removeRows = model->rowCount(); Models::AddEntry(model, tr("None"), NET_TYPE_NONE); Models::AddEntry(model, "SLiRP", NET_TYPE_SLIRP); @@ -128,9 +133,9 @@ void SettingsNetwork::onCurrentMachineChanged(int machineId) { selectedRow = 0; QString currentPcapDevice = net_cards_conf[i].host_dev_name; - cbox = findChild(QString("comboBoxIntf%1").arg(i+1)); - model = cbox->model(); - removeRows = model->rowCount(); + cbox = findChild(QString("comboBoxIntf%1").arg(i + 1)); + model = cbox->model(); + removeRows = model->rowCount(); for (int c = 0; c < network_ndev; c++) { Models::AddEntry(model, tr(network_devs[c].description), c); if (QString(network_devs[c].device) == currentPcapDevice) { @@ -142,7 +147,9 @@ void SettingsNetwork::onCurrentMachineChanged(int machineId) { } } -void SettingsNetwork::on_comboIndexChanged(int index) { +void +SettingsNetwork::on_comboIndexChanged(int index) +{ if (index < 0) { return; } @@ -150,18 +157,26 @@ void SettingsNetwork::on_comboIndexChanged(int index) { enableElements(ui); } -void SettingsNetwork::on_pushButtonConf1_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC1->currentData().toInt()), 1, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf1_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC1->currentData().toInt()), 1, qobject_cast(Settings::settings)); } -void SettingsNetwork::on_pushButtonConf2_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC2->currentData().toInt()), 2, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf2_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC2->currentData().toInt()), 2, qobject_cast(Settings::settings)); } -void SettingsNetwork::on_pushButtonConf3_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC3->currentData().toInt()), 3, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf3_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC3->currentData().toInt()), 3, qobject_cast(Settings::settings)); } -void SettingsNetwork::on_pushButtonConf4_clicked() { - DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC4->currentData().toInt()), 4, qobject_cast(Settings::settings)); +void +SettingsNetwork::on_pushButtonConf4_clicked() +{ + DeviceConfig::ConfigureDevice(network_card_getdevice(ui->comboBoxNIC4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsnetwork.hpp b/src/qt/qt_settingsnetwork.hpp index 55d983b5f..d39d90896 100644 --- a/src/qt/qt_settingsnetwork.hpp +++ b/src/qt/qt_settingsnetwork.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsNetwork; } -class SettingsNetwork : public QWidget -{ +class SettingsNetwork : public QWidget { Q_OBJECT public: @@ -31,7 +30,7 @@ private slots: private: Ui::SettingsNetwork *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSNETWORK_HPP diff --git a/src/qt/qt_settingsotherperipherals.cpp b/src/qt/qt_settingsotherperipherals.cpp index ebf849d28..edffd360a 100644 --- a/src/qt/qt_settingsotherperipherals.cpp +++ b/src/qt/qt_settingsotherperipherals.cpp @@ -28,15 +28,16 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsOtherPeripherals::SettingsOtherPeripherals(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsOtherPeripherals) +SettingsOtherPeripherals::SettingsOtherPeripherals(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsOtherPeripherals) { ui->setupUi(this); onCurrentMachineChanged(machine); } -void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) +void +SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) { this->machineId = machineId; @@ -52,9 +53,9 @@ void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->comboBoxCard4->clear(); ui->comboBoxRTC->clear(); - auto* model = ui->comboBoxRTC->model(); - int d = 0; - int selectedRow = 0; + auto *model = ui->comboBoxRTC->model(); + int d = 0; + int selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(isartc_get_device(d), isartc_get_internal_name(d), 0); if (name.isEmpty()) { @@ -74,9 +75,9 @@ void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) ui->comboBoxRTC->setCurrentIndex(selectedRow); for (int c = 0; c < ISAMEM_MAX; c++) { - auto* cbox = findChild(QString("comboBoxCard%1").arg(c + 1)); - model = cbox->model(); - d = 0; + auto *cbox = findChild(QString("comboBoxCard%1").arg(c + 1)); + model = cbox->model(); + d = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(isamem_get_device(d), isamem_get_internal_name(d), 0); @@ -97,7 +98,7 @@ void SettingsOtherPeripherals::onCurrentMachineChanged(int machineId) cbox->setCurrentIndex(-1); cbox->setCurrentIndex(selectedRow); cbox->setEnabled(machine_has_bus(machineId, MACHINE_BUS_ISA)); - findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); + findChild(QString("pushButtonConfigureCard%1").arg(c + 1))->setEnabled(isamem_type[c] != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } } @@ -106,70 +107,92 @@ SettingsOtherPeripherals::~SettingsOtherPeripherals() delete ui; } -void SettingsOtherPeripherals::save() { +void +SettingsOtherPeripherals::save() +{ /* Other peripherals category */ - bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; + bugger_enabled = ui->checkBoxISABugger->isChecked() ? 1 : 0; postcard_enabled = ui->checkBoxPOSTCard->isChecked() ? 1 : 0; - isartc_type = ui->comboBoxRTC->currentData().toInt(); + isartc_type = ui->comboBoxRTC->currentData().toInt(); /* ISA memory boards. */ for (int i = 0; i < ISAMEM_MAX; i++) { - auto* cbox = findChild(QString("comboBoxCard%1").arg(i + 1)); + auto *cbox = findChild(QString("comboBoxCard%1").arg(i + 1)); isamem_type[i] = cbox->currentData().toInt(); } } -void SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxRTC_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureRTC->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureRTC_clicked() { - DeviceConfig::ConfigureDevice(isartc_get_device(ui->comboBoxRTC->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureRTC_clicked() +{ + DeviceConfig::ConfigureDevice(isartc_get_device(ui->comboBoxRTC->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard1_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard1->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard1_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard1->currentData().toInt()), 1, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard1_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard1->currentData().toInt()), 1, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard2_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard2->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard2_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard2->currentData().toInt()), 2, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard2_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard2->currentData().toInt()), 2, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard3_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard3->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard3_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard3->currentData().toInt()), 3, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard3_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard3->currentData().toInt()), 3, qobject_cast(Settings::settings)); } -void SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) { +void +SettingsOtherPeripherals::on_comboBoxCard4_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureCard4->setEnabled(index != 0 && machine_has_bus(machineId, MACHINE_BUS_ISA)); } -void SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() { - DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); +void +SettingsOtherPeripherals::on_pushButtonConfigureCard4_clicked() +{ + DeviceConfig::ConfigureDevice(isamem_get_device(ui->comboBoxCard4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsotherperipherals.hpp b/src/qt/qt_settingsotherperipherals.hpp index f8eed2c9e..97e47c90e 100644 --- a/src/qt/qt_settingsotherperipherals.hpp +++ b/src/qt/qt_settingsotherperipherals.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsOtherPeripherals; } -class SettingsOtherPeripherals : public QWidget -{ +class SettingsOtherPeripherals : public QWidget { Q_OBJECT public: @@ -34,7 +33,7 @@ private slots: private: Ui::SettingsOtherPeripherals *ui; - int machineId{0}; + int machineId { 0 }; }; #endif // QT_SETTINGSOTHERPERIPHERALS_HPP diff --git a/src/qt/qt_settingsotherremovable.cpp b/src/qt/qt_settingsotherremovable.cpp index 574fdccb5..f625388ea 100644 --- a/src/qt/qt_settingsotherremovable.cpp +++ b/src/qt/qt_settingsotherremovable.cpp @@ -33,20 +33,24 @@ extern "C" { #include "qt_settings_bus_tracking.hpp" #include "qt_progsettings.hpp" -static QString moDriveTypeName(int i) { +static QString +moDriveTypeName(int i) +{ return QString("%1 %2 %3").arg(mo_drive_types[i].vendor, mo_drive_types[i].model, mo_drive_types[i].revision); } -static void setMOBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { +static void +setMOBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +{ QIcon icon; switch (bus) { - case MO_BUS_DISABLED: - icon = ProgSettings::loadIcon("/mo_disabled.ico"); - break; - case MO_BUS_ATAPI: - case MO_BUS_SCSI: - icon = ProgSettings::loadIcon("/mo.ico"); - break; + case MO_BUS_DISABLED: + icon = ProgSettings::loadIcon("/mo_disabled.ico"); + break; + case MO_BUS_ATAPI: + case MO_BUS_SCSI: + icon = ProgSettings::loadIcon("/mo.ico"); + break; } auto i = idx.siblingAtColumn(0); @@ -56,7 +60,9 @@ static void setMOBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t model->setData(i, icon, Qt::DecorationRole); } -static void setMOType(QAbstractItemModel* model, const QModelIndex& idx, uint32_t type) { +static void +setMOType(QAbstractItemModel *model, const QModelIndex &idx, uint32_t type) +{ auto i = idx.siblingAtColumn(1); if (idx.siblingAtColumn(0).data(Qt::UserRole).toUInt() == MO_BUS_DISABLED) { model->setData(i, QCoreApplication::translate("", "None")); @@ -66,16 +72,18 @@ static void setMOType(QAbstractItemModel* model, const QModelIndex& idx, uint32_ model->setData(i, type, Qt::UserRole); } -static void setZIPBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t bus, uint8_t channel) { +static void +setZIPBus(QAbstractItemModel *model, const QModelIndex &idx, uint8_t bus, uint8_t channel) +{ QIcon icon; switch (bus) { - case ZIP_BUS_DISABLED: - icon = ProgSettings::loadIcon("/zip_disabled.ico"); - break; - case ZIP_BUS_ATAPI: - case ZIP_BUS_SCSI: - icon = ProgSettings::loadIcon("/zip.ico"); - break; + case ZIP_BUS_DISABLED: + icon = ProgSettings::loadIcon("/zip_disabled.ico"); + break; + case ZIP_BUS_ATAPI: + case ZIP_BUS_SCSI: + icon = ProgSettings::loadIcon("/zip.ico"); + break; } auto i = idx.siblingAtColumn(0); @@ -85,20 +93,22 @@ static void setZIPBus(QAbstractItemModel* model, const QModelIndex& idx, uint8_t model->setData(i, icon, Qt::DecorationRole); } -static void setZIPType(QAbstractItemModel* model, const QModelIndex& idx, bool is250) { +static void +setZIPType(QAbstractItemModel *model, const QModelIndex &idx, bool is250) +{ auto i = idx.siblingAtColumn(1); model->setData(i, is250 ? "ZIP 250" : "ZIP 100"); model->setData(i, is250, Qt::UserRole); } -SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsOtherRemovable) +SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsOtherRemovable) { ui->setupUi(this); Harddrives::populateRemovableBuses(ui->comboBoxMOBus->model()); - auto* model = ui->comboBoxMOType->model(); + auto *model = ui->comboBoxMOType->model(); for (uint32_t i = 0; i < KNOWN_MO_DRIVE_TYPES; i++) { Models::AddEntry(model, moDriveTypeName(i), i); } @@ -120,9 +130,6 @@ SettingsOtherRemovable::SettingsOtherRemovable(QWidget *parent) : connect(ui->tableViewMO->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &SettingsOtherRemovable::onMORowChanged); ui->tableViewMO->setCurrentIndex(model->index(0, 0)); - - - Harddrives::populateRemovableBuses(ui->comboBoxZIPBus->model()); model = new QStandardItemModel(0, 2, this); @@ -148,79 +155,89 @@ SettingsOtherRemovable::~SettingsOtherRemovable() delete ui; } -void SettingsOtherRemovable::save() { - auto* model = ui->tableViewMO->model(); +void +SettingsOtherRemovable::save() +{ + auto *model = ui->tableViewMO->model(); for (int i = 0; i < MO_NUM; i++) { - mo_drives[i].f = NULL; - mo_drives[i].priv = NULL; + mo_drives[i].f = NULL; + mo_drives[i].priv = NULL; mo_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); - mo_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); - mo_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); + mo_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + mo_drives[i].type = model->index(i, 1).data(Qt::UserRole).toUInt(); } model = ui->tableViewZIP->model(); for (int i = 0; i < ZIP_NUM; i++) { - zip_drives[i].f = NULL; - zip_drives[i].priv = NULL; + zip_drives[i].f = NULL; + zip_drives[i].priv = NULL; zip_drives[i].bus_type = model->index(i, 0).data(Qt::UserRole).toUInt(); - zip_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); - zip_drives[i].is_250 = model->index(i, 1).data(Qt::UserRole).toBool() ? 1 : 0; + zip_drives[i].res = model->index(i, 0).data(Qt::UserRole + 1).toUInt(); + zip_drives[i].is_250 = model->index(i, 1).data(Qt::UserRole).toBool() ? 1 : 0; } } -void SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) { - uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); +void +SettingsOtherRemovable::onMORowChanged(const QModelIndex ¤t) +{ + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); + uint8_t type = current.siblingAtColumn(1).data(Qt::UserRole).toUInt(); ui->comboBoxMOBus->setCurrentIndex(-1); - auto* model = ui->comboBoxMOBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxMOBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxMOBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxMOChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxMOChannel->setCurrentIndex(match.first().row()); } ui->comboBoxMOType->setCurrentIndex(type); } -void SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) { - uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); +void +SettingsOtherRemovable::onZIPRowChanged(const QModelIndex ¤t) +{ + uint8_t bus = current.siblingAtColumn(0).data(Qt::UserRole).toUInt(); uint8_t channel = current.siblingAtColumn(0).data(Qt::UserRole + 1).toUInt(); - bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); + bool is250 = current.siblingAtColumn(1).data(Qt::UserRole).toBool(); ui->comboBoxZIPBus->setCurrentIndex(-1); - auto* model = ui->comboBoxZIPBus->model(); - auto match = model->match(model->index(0, 0), Qt::UserRole, bus); - if (! match.isEmpty()) { + auto *model = ui->comboBoxZIPBus->model(); + auto match = model->match(model->index(0, 0), Qt::UserRole, bus); + if (!match.isEmpty()) { ui->comboBoxZIPBus->setCurrentIndex(match.first().row()); } model = ui->comboBoxZIPChannel->model(); match = model->match(model->index(0, 0), Qt::UserRole, channel); - if (! match.isEmpty()) { + if (!match.isEmpty()) { ui->comboBoxZIPChannel->setCurrentIndex(match.first().row()); } ui->checkBoxZIP250->setChecked(is250); } -void SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) { +void +SettingsOtherRemovable::on_comboBoxMOBus_currentIndexChanged(int index) +{ if (index < 0) { return; } - int bus = ui->comboBoxMOBus->currentData().toInt(); + int bus = ui->comboBoxMOBus->currentData().toInt(); bool enabled = (bus != MO_BUS_DISABLED); ui->comboBoxMOChannel->setEnabled(enabled); ui->comboBoxMOType->setEnabled(enabled); Harddrives::populateBusChannels(ui->comboBoxMOChannel->model(), bus); } -void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { +void +SettingsOtherRemovable::on_comboBoxMOBus_activated(int) +{ auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); ui->comboBoxMOChannel->setCurrentIndex(ui->comboBoxMOBus->currentData().toUInt() == MO_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); @@ -239,7 +256,9 @@ void SettingsOtherRemovable::on_comboBoxMOBus_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { +void +SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) +{ auto i = ui->tableViewMO->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); setMOBus( @@ -250,7 +269,9 @@ void SettingsOtherRemovable::on_comboBoxMOChannel_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_MO, ui->tableViewMO->model()->data(i, Qt::UserRole).toInt(), ui->tableViewMO->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { +void +SettingsOtherRemovable::on_comboBoxMOType_activated(int) +{ setMOType( ui->tableViewMO->model(), ui->tableViewMO->selectionModel()->currentIndex(), @@ -259,19 +280,23 @@ void SettingsOtherRemovable::on_comboBoxMOType_activated(int) { ui->tableViewMO->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); } -void SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) { +void +SettingsOtherRemovable::on_comboBoxZIPBus_currentIndexChanged(int index) +{ if (index < 0) { return; } - int bus = ui->comboBoxZIPBus->currentData().toInt(); + int bus = ui->comboBoxZIPBus->currentData().toInt(); bool enabled = (bus != ZIP_BUS_DISABLED); ui->comboBoxZIPChannel->setEnabled(enabled); ui->checkBoxZIP250->setEnabled(enabled); Harddrives::populateBusChannels(ui->comboBoxZIPChannel->model(), bus); } -void SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) { +void +SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) +{ auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); ui->comboBoxZIPChannel->setCurrentIndex(ui->comboBoxZIPBus->currentData().toUInt() == ZIP_BUS_ATAPI ? Harddrives::busTrackClass->next_free_ide_channel() : Harddrives::busTrackClass->next_free_scsi_id()); @@ -283,7 +308,9 @@ void SettingsOtherRemovable::on_comboBoxZIPBus_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) { +void +SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) +{ auto i = ui->tableViewZIP->selectionModel()->currentIndex().siblingAtColumn(0); Harddrives::busTrackClass->device_track(0, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); setZIPBus( @@ -294,7 +321,9 @@ void SettingsOtherRemovable::on_comboBoxZIPChannel_activated(int) { Harddrives::busTrackClass->device_track(1, DEV_ZIP, ui->tableViewZIP->model()->data(i, Qt::UserRole).toInt(), ui->tableViewZIP->model()->data(i, Qt::UserRole + 1).toInt()); } -void SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) { +void +SettingsOtherRemovable::on_checkBoxZIP250_stateChanged(int state) +{ setZIPType( ui->tableViewZIP->model(), ui->tableViewZIP->selectionModel()->currentIndex(), diff --git a/src/qt/qt_settingsotherremovable.hpp b/src/qt/qt_settingsotherremovable.hpp index c48f6f819..8b81fb0f0 100644 --- a/src/qt/qt_settingsotherremovable.hpp +++ b/src/qt/qt_settingsotherremovable.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsOtherRemovable; } -class SettingsOtherRemovable : public QWidget -{ +class SettingsOtherRemovable : public QWidget { Q_OBJECT public: diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index 34c000c87..dfa2c8853 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -32,19 +32,19 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsPorts::SettingsPorts(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsPorts) +SettingsPorts::SettingsPorts(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsPorts) { ui->setupUi(this); for (int i = 0; i < PARALLEL_MAX; i++) { - auto* cbox = findChild(QString("comboBoxLpt%1").arg(i+1)); - auto* model = cbox->model(); - int c = 0; - int selectedRow = 0; + auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); + auto *model = cbox->model(); + int c = 0; + int selectedRow = 0; while (true) { - const char* lptName = lpt_device_get_name(c); + const char *lptName = lpt_device_get_name(c); if (lptName == nullptr) { break; } @@ -57,13 +57,13 @@ SettingsPorts::SettingsPorts(QWidget *parent) : } cbox->setCurrentIndex(selectedRow); - auto* checkBox = findChild(QString("checkBoxParallel%1").arg(i+1)); + auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); checkBox->setChecked(lpt_ports[i].enabled > 0); cbox->setEnabled(lpt_ports[i].enabled > 0); } for (int i = 0; i < SERIAL_MAX; i++) { - auto* checkBox = findChild(QString("checkBoxSerial%1").arg(i+1)); + auto *checkBox = findChild(QString("checkBoxSerial%1").arg(i + 1)); checkBox->setChecked(com_ports[i].enabled > 0); } } @@ -73,32 +73,42 @@ SettingsPorts::~SettingsPorts() delete ui; } -void SettingsPorts::save() { +void +SettingsPorts::save() +{ for (int i = 0; i < PARALLEL_MAX; i++) { - auto* cbox = findChild(QString("comboBoxLpt%1").arg(i+1)); - auto* checkBox = findChild(QString("checkBoxParallel%1").arg(i+1)); - lpt_ports[i].device = cbox->currentData().toInt(); + auto *cbox = findChild(QString("comboBoxLpt%1").arg(i + 1)); + auto *checkBox = findChild(QString("checkBoxParallel%1").arg(i + 1)); + lpt_ports[i].device = cbox->currentData().toInt(); lpt_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } for (int i = 0; i < SERIAL_MAX; i++) { - auto* checkBox = findChild(QString("checkBoxSerial%1").arg(i+1)); + auto *checkBox = findChild(QString("checkBoxSerial%1").arg(i + 1)); com_ports[i].enabled = checkBox->isChecked() ? 1 : 0; } } -void SettingsPorts::on_checkBoxParallel1_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel1_stateChanged(int state) +{ ui->comboBoxLpt1->setEnabled(state == Qt::Checked); } -void SettingsPorts::on_checkBoxParallel2_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel2_stateChanged(int state) +{ ui->comboBoxLpt2->setEnabled(state == Qt::Checked); } -void SettingsPorts::on_checkBoxParallel3_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel3_stateChanged(int state) +{ ui->comboBoxLpt3->setEnabled(state == Qt::Checked); } -void SettingsPorts::on_checkBoxParallel4_stateChanged(int state) { +void +SettingsPorts::on_checkBoxParallel4_stateChanged(int state) +{ ui->comboBoxLpt4->setEnabled(state == Qt::Checked); } diff --git a/src/qt/qt_settingsports.hpp b/src/qt/qt_settingsports.hpp index c5deef80a..5fa88e210 100644 --- a/src/qt/qt_settingsports.hpp +++ b/src/qt/qt_settingsports.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsPorts; } -class SettingsPorts : public QWidget -{ +class SettingsPorts : public QWidget { Q_OBJECT public: diff --git a/src/qt/qt_settingssound.cpp b/src/qt/qt_settingssound.cpp index 1c441b8ef..57686f7df 100644 --- a/src/qt/qt_settingssound.cpp +++ b/src/qt/qt_settingssound.cpp @@ -31,9 +31,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsSound::SettingsSound(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsSound) +SettingsSound::SettingsSound(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsSound) { ui->setupUi(this); onCurrentMachineChanged(machine); @@ -44,28 +44,35 @@ SettingsSound::~SettingsSound() delete ui; } -void SettingsSound::save() { - sound_card_current = ui->comboBoxSoundCard->currentData().toInt(); +void +SettingsSound::save() +{ + sound_card_current = ui->comboBoxSoundCard->currentData().toInt(); midi_output_device_current = ui->comboBoxMidiOut->currentData().toInt(); - midi_input_device_current = ui->comboBoxMidiIn->currentData().toInt(); - mpu401_standalone_enable = ui->checkBoxMPU401->isChecked() ? 1 : 0; - SSI2001 = ui->checkBoxSSI2001->isChecked() ? 1 : 0;; + midi_input_device_current = ui->comboBoxMidiIn->currentData().toInt(); + mpu401_standalone_enable = ui->checkBoxMPU401->isChecked() ? 1 : 0; + SSI2001 = ui->checkBoxSSI2001->isChecked() ? 1 : 0; + ; GAMEBLASTER = ui->checkBoxCMS->isChecked() ? 1 : 0; - GUS = ui->checkBoxGUS->isChecked() ? 1 : 0;; - sound_is_float = ui->checkBoxFloat32->isChecked() ? 1 : 0;; + GUS = ui->checkBoxGUS->isChecked() ? 1 : 0; + ; + sound_is_float = ui->checkBoxFloat32->isChecked() ? 1 : 0; + ; if (ui->radioButtonYMFM->isChecked()) fm_driver = FM_DRV_YMFM; else fm_driver = FM_DRV_NUKED; } -void SettingsSound::onCurrentMachineChanged(int machineId) { +void +SettingsSound::onCurrentMachineChanged(int machineId) +{ this->machineId = machineId; - auto* model = ui->comboBoxSoundCard->model(); - auto removeRows = model->rowCount(); - int c = 0; - int selectedRow = 0; + auto *model = ui->comboBoxSoundCard->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ if ((c == 1) && (machine_has_flags(machineId, MACHINE_SOUND) == 0)) { @@ -73,8 +80,8 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { continue; } - auto* sound_dev = sound_card_getdevice(c); - QString name = DeviceConfig::DeviceName(sound_dev, sound_card_get_internal_name(c), 1); + auto *sound_dev = sound_card_getdevice(c); + QString name = DeviceConfig::DeviceName(sound_dev, sound_card_get_internal_name(c), 1); if (name.isEmpty()) { break; } @@ -95,9 +102,9 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->comboBoxSoundCard->setCurrentIndex(-1); ui->comboBoxSoundCard->setCurrentIndex(selectedRow); - model = ui->comboBoxMidiOut->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxMidiOut->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(midi_out_device_getdevice(c), midi_out_device_get_internal_name(c), 0); @@ -118,9 +125,9 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->comboBoxMidiOut->setCurrentIndex(-1); ui->comboBoxMidiOut->setCurrentIndex(selectedRow); - model = ui->comboBoxMidiIn->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxMidiIn->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(midi_in_device_getdevice(c), midi_in_device_get_internal_name(c), 0); @@ -148,7 +155,7 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->checkBoxGUS->setChecked(GUS > 0); ui->checkBoxFloat32->setChecked(sound_is_float > 0); - bool hasIsa = machine_has_bus(machineId, MACHINE_BUS_ISA) > 0; + bool hasIsa = machine_has_bus(machineId, MACHINE_BUS_ISA) > 0; bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; ui->checkBoxCMS->setEnabled(hasIsa); ui->pushButtonConfigureCMS->setEnabled((GAMEBLASTER > 0) && hasIsa); @@ -157,17 +164,19 @@ void SettingsSound::onCurrentMachineChanged(int machineId) { ui->checkBoxSSI2001->setEnabled(hasIsa); ui->pushButtonConfigureSSI2001->setEnabled((SSI2001 > 0) && hasIsa); switch (fm_driver) { - case FM_DRV_YMFM: - ui->radioButtonYMFM->setChecked(true); - break; - case FM_DRV_NUKED: - default: - ui->radioButtonNuked->setChecked(true); - break; + case FM_DRV_YMFM: + ui->radioButtonYMFM->setChecked(true); + break; + case FM_DRV_NUKED: + default: + ui->radioButtonNuked->setChecked(true); + break; } } -static bool allowMpu401(Ui::SettingsSound *ui) { +static bool +allowMpu401(Ui::SettingsSound *ui) +{ QString midiOut = midi_out_device_get_internal_name(ui->comboBoxMidiOut->currentData().toInt()); QString midiIn = midi_in_device_get_internal_name(ui->comboBoxMidiIn->currentData().toInt()); @@ -182,19 +191,24 @@ static bool allowMpu401(Ui::SettingsSound *ui) { return true; } -void SettingsSound::on_comboBoxSoundCard_currentIndexChanged(int index) { +void +SettingsSound::on_comboBoxSoundCard_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonConfigureSoundCard->setEnabled(sound_card_has_config(ui->comboBoxSoundCard->currentData().toInt())); } - -void SettingsSound::on_pushButtonConfigureSoundCard_clicked() { - DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureSoundCard_clicked() +{ + DeviceConfig::ConfigureDevice(sound_card_getdevice(ui->comboBoxSoundCard->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) { +void +SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) +{ if (index < 0) { return; } @@ -203,11 +217,15 @@ void SettingsSound::on_comboBoxMidiOut_currentIndexChanged(int index) { ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked()); } -void SettingsSound::on_pushButtonConfigureMidiOut_clicked() { - DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureMidiOut_clicked() +{ + DeviceConfig::ConfigureDevice(midi_out_device_getdevice(ui->comboBoxMidiOut->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) { +void +SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) +{ if (index < 0) { return; } @@ -216,42 +234,60 @@ void SettingsSound::on_comboBoxMidiIn_currentIndexChanged(int index) { ui->pushButtonConfigureMPU401->setEnabled(allowMpu401(ui) && ui->checkBoxMPU401->isChecked()); } -void SettingsSound::on_pushButtonConfigureMidiIn_clicked() { - DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureMidiIn_clicked() +{ + DeviceConfig::ConfigureDevice(midi_in_device_getdevice(ui->comboBoxMidiIn->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_checkBoxMPU401_stateChanged(int state) { +void +SettingsSound::on_checkBoxMPU401_stateChanged(int state) +{ ui->pushButtonConfigureMPU401->setEnabled(state == Qt::Checked); } -void SettingsSound::on_checkBoxSSI2001_stateChanged(int state) { +void +SettingsSound::on_checkBoxSSI2001_stateChanged(int state) +{ ui->pushButtonConfigureSSI2001->setEnabled(state == Qt::Checked); } -void SettingsSound::on_checkBoxCMS_stateChanged(int state) { +void +SettingsSound::on_checkBoxCMS_stateChanged(int state) +{ ui->pushButtonConfigureCMS->setEnabled(state == Qt::Checked); } -void SettingsSound::on_checkBoxGUS_stateChanged(int state) { +void +SettingsSound::on_checkBoxGUS_stateChanged(int state) +{ ui->pushButtonConfigureGUS->setEnabled(state == Qt::Checked); } -void SettingsSound::on_pushButtonConfigureMPU401_clicked() { +void +SettingsSound::on_pushButtonConfigureMPU401_clicked() +{ if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { - DeviceConfig::ConfigureDevice(&mpu401_mca_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&mpu401_mca_device, 0, qobject_cast(Settings::settings)); } else { - DeviceConfig::ConfigureDevice(&mpu401_device, 0, qobject_cast(Settings::settings)); + DeviceConfig::ConfigureDevice(&mpu401_device, 0, qobject_cast(Settings::settings)); } } -void SettingsSound::on_pushButtonConfigureSSI2001_clicked() { - DeviceConfig::ConfigureDevice(&ssi2001_device, 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureSSI2001_clicked() +{ + DeviceConfig::ConfigureDevice(&ssi2001_device, 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_pushButtonConfigureCMS_clicked() { - DeviceConfig::ConfigureDevice(&cms_device, 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureCMS_clicked() +{ + DeviceConfig::ConfigureDevice(&cms_device, 0, qobject_cast(Settings::settings)); } -void SettingsSound::on_pushButtonConfigureGUS_clicked() { - DeviceConfig::ConfigureDevice(&gus_device, 0, qobject_cast(Settings::settings)); +void +SettingsSound::on_pushButtonConfigureGUS_clicked() +{ + DeviceConfig::ConfigureDevice(&gus_device, 0, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingssound.hpp b/src/qt/qt_settingssound.hpp index c649eb2a2..e0bc2e4f8 100644 --- a/src/qt/qt_settingssound.hpp +++ b/src/qt/qt_settingssound.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsSound; } -class SettingsSound : public QWidget -{ +class SettingsSound : public QWidget { Q_OBJECT public: @@ -38,7 +37,7 @@ private slots: private: Ui::SettingsSound *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSSOUND_HPP diff --git a/src/qt/qt_settingsstoragecontrollers.cpp b/src/qt/qt_settingsstoragecontrollers.cpp index 7664fdd5f..2aecab568 100644 --- a/src/qt/qt_settingsstoragecontrollers.cpp +++ b/src/qt/qt_settingsstoragecontrollers.cpp @@ -33,9 +33,9 @@ extern "C" { #include "qt_deviceconfig.hpp" #include "qt_models_common.hpp" -SettingsStorageControllers::SettingsStorageControllers(QWidget *parent) : - QWidget(parent), - ui(new Ui::SettingsStorageControllers) +SettingsStorageControllers::SettingsStorageControllers(QWidget *parent) + : QWidget(parent) + , ui(new Ui::SettingsStorageControllers) { ui->setupUi(this); @@ -49,27 +49,31 @@ SettingsStorageControllers::~SettingsStorageControllers() delete ui; } -void SettingsStorageControllers::save() { +void +SettingsStorageControllers::save() +{ /* Storage devices category */ for (int i = 0; i < SCSI_BUS_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxSCSI%1").arg(i+1)); + auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); scsi_card_current[i] = cbox->currentData().toInt(); } - hdc_current = ui->comboBoxHD->currentData().toInt(); - fdc_type = ui->comboBoxFD->currentData().toInt(); + hdc_current = ui->comboBoxHD->currentData().toInt(); + fdc_type = ui->comboBoxFD->currentData().toInt(); ide_ter_enabled = ui->checkBoxTertiaryIDE->isChecked() ? 1 : 0; ide_qua_enabled = ui->checkBoxQuaternaryIDE->isChecked() ? 1 : 0; cassette_enable = ui->checkBoxCassette->isChecked() ? 1 : 0; } -void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { +void +SettingsStorageControllers::onCurrentMachineChanged(int machineId) +{ this->machineId = machineId; /*HD controller config*/ - auto* model = ui->comboBoxHD->model(); - auto removeRows = model->rowCount(); - int c = 0; - int selectedRow = 0; + auto *model = ui->comboBoxHD->model(); + auto removeRows = model->rowCount(); + int c = 0; + int selectedRow = 0; while (true) { /* Skip "internal" if machine doesn't have it. */ if ((c == 1) && (machine_has_flags(machineId, MACHINE_HDC) == 0)) { @@ -83,7 +87,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { } if (hdc_available(c)) { - auto* hdc_dev = hdc_get_device(c); + auto *hdc_dev = hdc_get_device(c); if (device_is_valid(hdc_dev, machineId)) { int row = Models::AddEntry(model, name, c); @@ -100,9 +104,9 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { ui->comboBoxHD->setCurrentIndex(selectedRow); /*FD controller config*/ - model = ui->comboBoxFD->model(); - removeRows = model->rowCount(); - c = 0; + model = ui->comboBoxFD->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { QString name = DeviceConfig::DeviceName(fdc_card_getdevice(c), fdc_card_get_internal_name(c), 1); @@ -111,7 +115,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { } if (fdc_card_available(c)) { - auto* fdc_dev = fdc_card_getdevice(c); + auto *fdc_dev = fdc_card_getdevice(c); if (device_is_valid(fdc_dev, machineId)) { int row = Models::AddEntry(model, name, c); @@ -128,10 +132,10 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { ui->comboBoxFD->setCurrentIndex(selectedRow); for (int i = 0; i < SCSI_BUS_MAX; ++i) { - auto* cbox = findChild(QString("comboBoxSCSI%1").arg(i+1)); - model = cbox->model(); - removeRows = model->rowCount(); - c = 0; + auto *cbox = findChild(QString("comboBoxSCSI%1").arg(i + 1)); + model = cbox->model(); + removeRows = model->rowCount(); + c = 0; selectedRow = 0; while (true) { @@ -141,7 +145,7 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { } if (scsi_card_available(c)) { - auto* scsi_dev = scsi_card_getdevice(c); + auto *scsi_dev = scsi_card_getdevice(c); if (device_is_valid(scsi_dev, machineId)) { int row = Models::AddEntry(model, name, c); if (c == scsi_card_current[i]) { @@ -165,86 +169,116 @@ void SettingsStorageControllers::onCurrentMachineChanged(int machineId) { ui->checkBoxQuaternaryIDE->setChecked(ui->checkBoxQuaternaryIDE->isEnabled() && ide_qua_enabled); } -void SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxHD_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonHD->setEnabled(hdc_has_config(ui->comboBoxHD->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxFD_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonFD->setEnabled(hdc_has_config(ui->comboBoxFD->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1) { +void +SettingsStorageControllers::on_checkBoxTertiaryIDE_stateChanged(int arg1) +{ ui->pushButtonTertiaryIDE->setEnabled(arg1 == Qt::Checked); } - -void SettingsStorageControllers::on_checkBoxQuaternaryIDE_stateChanged(int arg1) { +void +SettingsStorageControllers::on_checkBoxQuaternaryIDE_stateChanged(int arg1) +{ ui->pushButtonQuaternaryIDE->setEnabled(arg1 == Qt::Checked); } -void SettingsStorageControllers::on_pushButtonHD_clicked() { - DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonHD_clicked() +{ + DeviceConfig::ConfigureDevice(hdc_get_device(ui->comboBoxHD->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonFD_clicked() { - DeviceConfig::ConfigureDevice(fdc_card_getdevice(ui->comboBoxFD->currentData().toInt()), 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonFD_clicked() +{ + DeviceConfig::ConfigureDevice(fdc_card_getdevice(ui->comboBoxFD->currentData().toInt()), 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonTertiaryIDE_clicked() { - DeviceConfig::ConfigureDevice(&ide_ter_device, 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonTertiaryIDE_clicked() +{ + DeviceConfig::ConfigureDevice(&ide_ter_device, 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonQuaternaryIDE_clicked() { - DeviceConfig::ConfigureDevice(&ide_qua_device, 0, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonQuaternaryIDE_clicked() +{ + DeviceConfig::ConfigureDevice(&ide_qua_device, 0, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_comboBoxSCSI1_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI1_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI1->setEnabled(scsi_card_has_config(ui->comboBoxSCSI1->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxSCSI2_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI2_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI2->setEnabled(scsi_card_has_config(ui->comboBoxSCSI2->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxSCSI3_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI3_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI3->setEnabled(scsi_card_has_config(ui->comboBoxSCSI3->currentData().toInt()) > 0); } -void SettingsStorageControllers::on_comboBoxSCSI4_currentIndexChanged(int index) { +void +SettingsStorageControllers::on_comboBoxSCSI4_currentIndexChanged(int index) +{ if (index < 0) { return; } ui->pushButtonSCSI4->setEnabled(scsi_card_has_config(ui->comboBoxSCSI4->currentData().toInt()) > 0); } - -void SettingsStorageControllers::on_pushButtonSCSI1_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI1->currentData().toInt()), 1, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI1_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI1->currentData().toInt()), 1, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonSCSI2_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI2->currentData().toInt()), 2, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI2_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI2->currentData().toInt()), 2, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonSCSI3_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI3->currentData().toInt()), 3, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI3_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI3->currentData().toInt()), 3, qobject_cast(Settings::settings)); } -void SettingsStorageControllers::on_pushButtonSCSI4_clicked() { - DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4, qobject_cast(Settings::settings)); +void +SettingsStorageControllers::on_pushButtonSCSI4_clicked() +{ + DeviceConfig::ConfigureDevice(scsi_card_getdevice(ui->comboBoxSCSI4->currentData().toInt()), 4, qobject_cast(Settings::settings)); } diff --git a/src/qt/qt_settingsstoragecontrollers.hpp b/src/qt/qt_settingsstoragecontrollers.hpp index e4596b567..7e9cd9d6c 100644 --- a/src/qt/qt_settingsstoragecontrollers.hpp +++ b/src/qt/qt_settingsstoragecontrollers.hpp @@ -7,8 +7,7 @@ namespace Ui { class SettingsStorageControllers; } -class SettingsStorageControllers : public QWidget -{ +class SettingsStorageControllers : public QWidget { Q_OBJECT public: @@ -40,7 +39,7 @@ private slots: private: Ui::SettingsStorageControllers *ui; - int machineId = 0; + int machineId = 0; }; #endif // QT_SETTINGSSTORAGECONTROLLERS_HPP diff --git a/src/qt/qt_softwarerenderer.cpp b/src/qt/qt_softwarerenderer.cpp index 44a69c144..cd27e1c0e 100644 --- a/src/qt/qt_softwarerenderer.cpp +++ b/src/qt/qt_softwarerenderer.cpp @@ -47,16 +47,21 @@ SoftwareRenderer::SoftwareRenderer(QWidget *parent) #endif } -void SoftwareRenderer::paintEvent(QPaintEvent* event) { - (void)event; +void +SoftwareRenderer::paintEvent(QPaintEvent *event) +{ + (void) event; onPaint(this); } -void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { +void +SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +{ /* TODO: should look into deleteLater() */ - auto tval = this; - void* nuldata = 0; - if (memcmp(&tval, &nuldata, sizeof(void*)) == 0) return; + auto tval = this; + void *nuldata = 0; + if (memcmp(&tval, &nuldata, sizeof(void *)) == 0) + return; auto origSource = source; cur_image = buf_idx; @@ -64,11 +69,14 @@ void SoftwareRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { source.setRect(x, y, w, h); - if (source != origSource) onResize(this->width(), this->height()); + if (source != origSource) + onResize(this->width(), this->height()); update(); } -void SoftwareRenderer::resizeEvent(QResizeEvent *event) { +void +SoftwareRenderer::resizeEvent(QResizeEvent *event) +{ onResize(width(), height()); #ifdef __HAIKU__ QWidget::resizeEvent(event); @@ -77,7 +85,8 @@ void SoftwareRenderer::resizeEvent(QResizeEvent *event) { #endif } -bool SoftwareRenderer::event(QEvent *event) +bool +SoftwareRenderer::event(QEvent *event) { bool res = false; if (!eventDelegate(event, res)) @@ -89,7 +98,9 @@ bool SoftwareRenderer::event(QEvent *event) return res; } -void SoftwareRenderer::onPaint(QPaintDevice* device) { +void +SoftwareRenderer::onPaint(QPaintDevice *device) +{ if (cur_image == -1) return; @@ -104,9 +115,10 @@ void SoftwareRenderer::onPaint(QPaintDevice* device) { painter.drawImage(destination, *images[cur_image], source); } -std::vector> SoftwareRenderer::getBuffers() +std::vector> +SoftwareRenderer::getBuffers() { - std::vector> buffers; + std::vector> buffers; buffers.push_back(std::make_tuple(images[0]->bits(), &buf_usage[0])); buffers.push_back(std::make_tuple(images[1]->bits(), &buf_usage[1])); diff --git a/src/qt/qt_softwarerenderer.hpp b/src/qt/qt_softwarerenderer.hpp index 5b0f7b0f5..ec64f7000 100644 --- a/src/qt/qt_softwarerenderer.hpp +++ b/src/qt/qt_softwarerenderer.hpp @@ -9,29 +9,28 @@ #include "qt_renderercommon.hpp" class SoftwareRenderer : - #ifdef __HAIKU__ - public QWidget, - #else - public QRasterWindow, - #endif - public RendererCommon -{ +#ifdef __HAIKU__ + public QWidget, +#else + public QRasterWindow, +#endif + public RendererCommon { Q_OBJECT public: explicit SoftwareRenderer(QWidget *parent = nullptr); - void paintEvent(QPaintEvent* event) override; + void paintEvent(QPaintEvent *event) override; - std::vector> getBuffers() override; + std::vector> getBuffers() override; public slots: void onBlit(int buf_idx, int x, int y, int w, int h); protected: std::array, 2> images; - int cur_image = -1; + int cur_image = -1; - void onPaint(QPaintDevice* device); + void onPaint(QPaintDevice *device); void resizeEvent(QResizeEvent *event) override; bool event(QEvent *event) override; }; diff --git a/src/qt/qt_soundgain.cpp b/src/qt/qt_soundgain.cpp index 26ac3dd73..9283ae42e 100644 --- a/src/qt/qt_soundgain.cpp +++ b/src/qt/qt_soundgain.cpp @@ -17,16 +17,15 @@ #include "qt_soundgain.hpp" #include "ui_qt_soundgain.h" -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/sound.h> } -SoundGain::SoundGain(QWidget *parent) : - QDialog(parent), - ui(new Ui::SoundGain) +SoundGain::SoundGain(QWidget *parent) + : QDialog(parent) + , ui(new Ui::SoundGain) { ui->setupUi(this); ui->verticalSlider->setValue(sound_gain); @@ -38,13 +37,14 @@ SoundGain::~SoundGain() delete ui; } -void SoundGain::on_verticalSlider_valueChanged(int value) +void +SoundGain::on_verticalSlider_valueChanged(int value) { sound_gain = value; } - -void SoundGain::on_SoundGain_rejected() +void +SoundGain::on_SoundGain_rejected() { sound_gain = sound_gain_orig; } diff --git a/src/qt/qt_soundgain.hpp b/src/qt/qt_soundgain.hpp index 0e19bab53..e4b52d959 100644 --- a/src/qt/qt_soundgain.hpp +++ b/src/qt/qt_soundgain.hpp @@ -7,8 +7,7 @@ namespace Ui { class SoundGain; } -class SoundGain : public QDialog -{ +class SoundGain : public QDialog { Q_OBJECT public: @@ -22,7 +21,7 @@ private slots: private: Ui::SoundGain *ui; - int sound_gain_orig; + int sound_gain_orig; }; #endif // QT_SOUNDGAIN_HPP diff --git a/src/qt/qt_specifydimensions.cpp b/src/qt/qt_specifydimensions.cpp index 1fc294d79..e2aa24a9b 100644 --- a/src/qt/qt_specifydimensions.cpp +++ b/src/qt/qt_specifydimensions.cpp @@ -27,19 +27,18 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/86box.h> #include <86box/plat.h> #include <86box/ui.h> #include <86box/video.h> } -extern MainWindow* main_window; +extern MainWindow *main_window; -SpecifyDimensions::SpecifyDimensions(QWidget *parent) : - QDialog(parent), - ui(new Ui::SpecifyDimensions) +SpecifyDimensions::SpecifyDimensions(QWidget *parent) + : QDialog(parent) + , ui(new Ui::SpecifyDimensions) { ui->setupUi(this); ui->checkBox->setChecked(vid_resize == 2); @@ -59,16 +58,16 @@ SpecifyDimensions::~SpecifyDimensions() delete ui; } -void SpecifyDimensions::on_SpecifyDimensions_accepted() +void +SpecifyDimensions::on_SpecifyDimensions_accepted() { - if (ui->checkBox->isChecked()) - { + if (ui->checkBox->isChecked()) { vid_resize = 2; main_window->setWindowFlag(Qt::WindowMaximizeButtonHint, false); main_window->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint); window_remember = 0; - fixed_size_x = ui->spinBoxWidth->value(); - fixed_size_y = ui->spinBoxHeight->value(); + fixed_size_x = ui->spinBoxWidth->value(); + fixed_size_y = ui->spinBoxHeight->value(); main_window->resizeContents(fixed_size_x, fixed_size_y); @@ -81,21 +80,19 @@ void SpecifyDimensions::on_SpecifyDimensions_accepted() emit main_window->resizeContentsMonitor(fixed_size_x, fixed_size_y, i); if (show_second_monitors) { main_window->renderers[i]->show(); - main_window->renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); + main_window->renderers[i]->switchRenderer((RendererStack::Renderer) vid_api); } } } - main_window->ui->stackedWidget->switchRenderer((RendererStack::Renderer)vid_api); - } - else - { + main_window->ui->stackedWidget->switchRenderer((RendererStack::Renderer) vid_api); + } else { main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); main_window->ui->actionResizable_window->setChecked(false); vid_resize = 0; main_window->ui->actionResizable_window->trigger(); window_remember = 1; - window_w = ui->spinBoxWidth->value(); - window_h = ui->spinBoxHeight->value(); + window_w = ui->spinBoxWidth->value(); + window_h = ui->spinBoxHeight->value(); main_window->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); emit main_window->resizeContents(ui->spinBoxWidth->value(), ui->spinBoxHeight->value()); for (int i = 1; i < MONITORS_NUM; i++) { @@ -104,8 +101,10 @@ void SpecifyDimensions::on_SpecifyDimensions_accepted() main_window->renderers[i]->setWindowFlag(Qt::MSWindowsFixedSizeDialogHint, false); emit main_window->resizeContentsMonitor(ui->spinBoxWidth->value(), ui->spinBoxHeight->value(), i); main_window->renderers[i]->setFixedSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX); - if (show_second_monitors) { main_window->renderers[i]->show(); - main_window->renderers[i]->switchRenderer((RendererStack::Renderer)vid_api); } + if (show_second_monitors) { + main_window->renderers[i]->show(); + main_window->renderers[i]->switchRenderer((RendererStack::Renderer) vid_api); + } } } vid_resize = 1; diff --git a/src/qt/qt_specifydimensions.h b/src/qt/qt_specifydimensions.h index 2aa820455..812e38707 100644 --- a/src/qt/qt_specifydimensions.h +++ b/src/qt/qt_specifydimensions.h @@ -7,8 +7,7 @@ namespace Ui { class SpecifyDimensions; } -class SpecifyDimensions : public QDialog -{ +class SpecifyDimensions : public QDialog { Q_OBJECT public: diff --git a/src/qt/qt_styleoverride.cpp b/src/qt/qt_styleoverride.cpp index a2af1296b..6efe523d9 100644 --- a/src/qt/qt_styleoverride.cpp +++ b/src/qt/qt_styleoverride.cpp @@ -19,11 +19,12 @@ #include #include -int StyleOverride::styleHint( - StyleHint hint, - const QStyleOption *option, - const QWidget *widget, - QStyleHintReturn *returnData) const +int +StyleOverride::styleHint( + StyleHint hint, + const QStyleOption *option, + const QWidget *widget, + QStyleHintReturn *returnData) const { /* Disable using menu with alt key */ if (hint == QStyle::SH_MenuBar_AltKeyNavigation) @@ -32,7 +33,8 @@ int StyleOverride::styleHint( return QProxyStyle::styleHint(hint, option, widget, returnData); } -void StyleOverride::polish(QWidget* widget) +void +StyleOverride::polish(QWidget *widget) { QProxyStyle::polish(widget); /* Disable title bar context help buttons globally as they are unused. */ @@ -48,7 +50,7 @@ void StyleOverride::polish(QWidget* widget) widget->setWindowFlag(Qt::WindowContextHelpButtonHint, false); } - if (qobject_cast(widget)) { - qobject_cast(widget)->view()->setMinimumWidth(widget->minimumSizeHint().width()); + if (qobject_cast(widget)) { + qobject_cast(widget)->view()->setMinimumWidth(widget->minimumSizeHint().width()); } } diff --git a/src/qt/qt_styleoverride.hpp b/src/qt/qt_styleoverride.hpp index 9a2223322..c04d01a12 100644 --- a/src/qt/qt_styleoverride.hpp +++ b/src/qt/qt_styleoverride.hpp @@ -5,16 +5,15 @@ #include #include -class StyleOverride : public QProxyStyle -{ +class StyleOverride : public QProxyStyle { public: int styleHint( - StyleHint hint, - const QStyleOption *option = nullptr, - const QWidget *widget = nullptr, - QStyleHintReturn *returnData = nullptr) const override; + StyleHint hint, + const QStyleOption *option = nullptr, + const QWidget *widget = nullptr, + QStyleHintReturn *returnData = nullptr) const override; - void polish(QWidget* widget) override; + void polish(QWidget *widget) override; }; #endif diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 09199bdac..a2864f3ea 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -27,7 +27,7 @@ #include "qt_mainwindow.hpp" #include "qt_machinestatus.hpp" -MainWindow* main_window = nullptr; +MainWindow *main_window = nullptr; static QString sb_text, sb_buguitext, sb_mt32lcdtext; @@ -60,7 +60,8 @@ plat_delay_ms(uint32_t count) QThread::msleep(count); } -wchar_t* ui_window_title(wchar_t* str) +wchar_t * +ui_window_title(wchar_t *str) { if (str == nullptr) { static wchar_t title[512]; @@ -73,49 +74,65 @@ wchar_t* ui_window_title(wchar_t* str) return str; } -extern "C" void qt_blit(int x, int y, int w, int h, int monitor_index) +extern "C" void +qt_blit(int x, int y, int w, int h, int monitor_index) { main_window->blitToWidget(x, y, w, h, monitor_index); } -void mouse_poll() { +void +mouse_poll() +{ main_window->pollMouse(); } extern "C" int vid_resize; -void plat_resize_request(int w, int h, int monitor_index) +void +plat_resize_request(int w, int h, int monitor_index) { - if (video_fullscreen || is_quit) return; + if (video_fullscreen || is_quit) + return; if (vid_resize & 2) { plat_resize_monitor(fixed_size_x, fixed_size_y, monitor_index); - } - else { + } else { plat_resize_monitor(w, h, monitor_index); } } -void plat_resize_monitor(int w, int h, int monitor_index) { - if (monitor_index >= 1) main_window->resizeContentsMonitor(w, h, monitor_index); - else main_window->resizeContents(w, h); +void +plat_resize_monitor(int w, int h, int monitor_index) +{ + if (monitor_index >= 1) + main_window->resizeContentsMonitor(w, h, monitor_index); + else + main_window->resizeContents(w, h); } -void plat_setfullscreen(int on) { +void +plat_setfullscreen(int on) +{ main_window->setFullscreen(on > 0 ? true : false); } -void plat_mouse_capture(int on) { +void +plat_mouse_capture(int on) +{ if (!kbd_req_capture && (mouse_type == MOUSE_TYPE_NONE) && !machine_has_mouse()) return; main_window->setMouseCapture(on > 0 ? true : false); } -int ui_msgbox_header(int flags, void *header, void* message) { - if (header <= (void*)7168) header = plat_get_string((uintptr_t)header); - if (message <= (void*)7168) message = plat_get_string((uintptr_t)message); +int +ui_msgbox_header(int flags, void *header, void *message) +{ + if (header <= (void *) 7168) + header = plat_get_string((uintptr_t) header); + if (message <= (void *) 7168) + message = plat_get_string((uintptr_t) message); - auto hdr = (flags & MBX_ANSI) ? QString((char*)header) : QString::fromWCharArray(reinterpret_cast(header)); - auto msg = (flags & MBX_ANSI) ? QString((char*)message) : QString::fromWCharArray(reinterpret_cast(message)); + auto hdr = (flags & MBX_ANSI) ? QString((char *) header) : QString::fromWCharArray(reinterpret_cast(header)); + auto msg = (flags & MBX_ANSI) ? QString((char *) message) : QString::fromWCharArray(reinterpret_cast(message)); // any error in early init if (main_window == nullptr) { @@ -129,60 +146,81 @@ int ui_msgbox_header(int flags, void *header, void* message) { return 0; } -void ui_init_monitor(int monitor_index) { +void +ui_init_monitor(int monitor_index) +{ if (QThread::currentThread() == main_window->thread()) { emit main_window->initRendererMonitor(monitor_index); - } - else emit main_window->initRendererMonitorForNonQtThread(monitor_index); + } else + emit main_window->initRendererMonitorForNonQtThread(monitor_index); } -void ui_deinit_monitor(int monitor_index) { +void +ui_deinit_monitor(int monitor_index) +{ if (QThread::currentThread() == main_window->thread()) { emit main_window->destroyRendererMonitor(monitor_index); - } - else emit main_window->destroyRendererMonitorForNonQtThread(monitor_index); + } else + emit main_window->destroyRendererMonitorForNonQtThread(monitor_index); } -int ui_msgbox(int flags, void *message) { +int +ui_msgbox(int flags, void *message) +{ return ui_msgbox_header(flags, nullptr, message); } -void ui_sb_update_text() { - emit main_window->statusBarMessage( !sb_mt32lcdtext.isEmpty() ? sb_mt32lcdtext : sb_text.isEmpty() ? sb_buguitext : sb_text); +void +ui_sb_update_text() +{ + emit main_window->statusBarMessage(!sb_mt32lcdtext.isEmpty() ? sb_mt32lcdtext : sb_text.isEmpty() ? sb_buguitext + : sb_text); } -void ui_sb_mt32lcd(char* str) +void +ui_sb_mt32lcd(char *str) { sb_mt32lcdtext = QString(str); ui_sb_update_text(); } -void ui_sb_set_text_w(wchar_t *wstr) { +void +ui_sb_set_text_w(wchar_t *wstr) +{ sb_text = QString::fromWCharArray(wstr); ui_sb_update_text(); } -void ui_sb_set_text(char *str) { +void +ui_sb_set_text(char *str) +{ sb_text = str; ui_sb_update_text(); } void -ui_sb_update_tip(int arg) { +ui_sb_update_tip(int arg) +{ main_window->updateStatusBarTip(arg); } void -ui_sb_update_panes() { +ui_sb_update_panes() +{ main_window->updateStatusBarPanes(); } -void ui_sb_bugui(char *str) { +void +ui_sb_bugui(char *str) +{ sb_buguitext = str; - ui_sb_update_text();; + ui_sb_update_text(); + ; } -void ui_sb_set_ready(int ready) { +void +ui_sb_set_ready(int ready) +{ if (ready == 0) { ui_sb_bugui(nullptr); ui_sb_set_text(nullptr); @@ -190,72 +228,73 @@ void ui_sb_set_ready(int ready) { } void -ui_sb_update_icon_state(int tag, int state) { +ui_sb_update_icon_state(int tag, int state) +{ int category = tag & 0xfffffff0; - int item = tag & 0xf; + int item = tag & 0xf; switch (category) { - case SB_CASSETTE: - machine_status.cassette.empty = state > 0 ? true : false; - break; - case SB_CARTRIDGE: - machine_status.cartridge[item].empty = state > 0 ? true : false; - break; - case SB_FLOPPY: - machine_status.fdd[item].empty = state > 0 ? true : false; - break; - case SB_CDROM: - machine_status.cdrom[item].empty = state > 0 ? true : false; - break; - case SB_ZIP: - machine_status.zip[item].empty = state > 0 ? true : false; - break; - case SB_MO: - machine_status.mo[item].empty = state > 0 ? true : false; - break; - case SB_HDD: - break; - case SB_NETWORK: - machine_status.net[item].empty = state > 0 ? true : false; - break; - case SB_SOUND: - break; - case SB_TEXT: - break; + case SB_CASSETTE: + machine_status.cassette.empty = state > 0 ? true : false; + break; + case SB_CARTRIDGE: + machine_status.cartridge[item].empty = state > 0 ? true : false; + break; + case SB_FLOPPY: + machine_status.fdd[item].empty = state > 0 ? true : false; + break; + case SB_CDROM: + machine_status.cdrom[item].empty = state > 0 ? true : false; + break; + case SB_ZIP: + machine_status.zip[item].empty = state > 0 ? true : false; + break; + case SB_MO: + machine_status.mo[item].empty = state > 0 ? true : false; + break; + case SB_HDD: + break; + case SB_NETWORK: + machine_status.net[item].empty = state > 0 ? true : false; + break; + case SB_SOUND: + break; + case SB_TEXT: + break; } } void -ui_sb_update_icon(int tag, int active) { +ui_sb_update_icon(int tag, int active) +{ int category = tag & 0xfffffff0; - int item = tag & 0xf; + int item = tag & 0xf; switch (category) { - case SB_CASSETTE: - break; - case SB_CARTRIDGE: - break; - case SB_FLOPPY: - machine_status.fdd[item].active = active > 0 ? true : false; - break; - case SB_CDROM: - machine_status.cdrom[item].active = active > 0 ? true : false; - break; - case SB_ZIP: - machine_status.zip[item].active = active > 0 ? true : false; - break; - case SB_MO: - machine_status.mo[item].active = active > 0 ? true : false; - break; - case SB_HDD: - machine_status.hdd[item].active = active > 0 ? true : false; - break; - case SB_NETWORK: - machine_status.net[item].active = active > 0 ? true : false; - break; - case SB_SOUND: - break; - case SB_TEXT: - break; + case SB_CASSETTE: + break; + case SB_CARTRIDGE: + break; + case SB_FLOPPY: + machine_status.fdd[item].active = active > 0 ? true : false; + break; + case SB_CDROM: + machine_status.cdrom[item].active = active > 0 ? true : false; + break; + case SB_ZIP: + machine_status.zip[item].active = active > 0 ? true : false; + break; + case SB_MO: + machine_status.mo[item].active = active > 0 ? true : false; + break; + case SB_HDD: + machine_status.hdd[item].active = active > 0 ? true : false; + break; + case SB_NETWORK: + machine_status.net[item].active = active > 0 ? true : false; + break; + case SB_SOUND: + break; + case SB_TEXT: + break; } } - } diff --git a/src/qt/qt_unixmanagerfilter.cpp b/src/qt/qt_unixmanagerfilter.cpp index 9df6da5cb..d1091198d 100644 --- a/src/qt/qt_unixmanagerfilter.cpp +++ b/src/qt/qt_unixmanagerfilter.cpp @@ -18,59 +18,44 @@ #include "qt_unixmanagerfilter.hpp" -UnixManagerSocket::UnixManagerSocket(QObject* obj) +UnixManagerSocket::UnixManagerSocket(QObject *obj) : QLocalSocket(obj) { connect(this, &QLocalSocket::readyRead, this, &UnixManagerSocket::readyToRead); } -void UnixManagerSocket::readyToRead() +void +UnixManagerSocket::readyToRead() { - if (canReadLine()) - { + if (canReadLine()) { QByteArray line = readLine(); - if (line.size()) - { + if (line.size()) { line.resize(line.size() - 1); - if (line == "showsettings") - { + if (line == "showsettings") { emit showsettings(); - } - else if (line == "pause") - { + } else if (line == "pause") { emit pause(); - } - else if (line == "cad") - { + } else if (line == "cad") { emit ctrlaltdel(); - } - else if (line == "reset") - { + } else if (line == "reset") { emit resetVM(); - } - else if (line == "shutdownnoprompt") - { + } else if (line == "shutdownnoprompt") { emit force_shutdown(); - } - else if (line == "shutdown") - { + } else if (line == "shutdown") { emit request_shutdown(); } } } } -bool UnixManagerSocket::eventFilter(QObject *obj, QEvent *event) +bool +UnixManagerSocket::eventFilter(QObject *obj, QEvent *event) { - if (state() == QLocalSocket::ConnectedState) - { - if (event->type() == QEvent::WindowBlocked) - { - write(QByteArray{"1"}); - } - else if (event->type() == QEvent::WindowUnblocked) - { - write(QByteArray{"0"}); + if (state() == QLocalSocket::ConnectedState) { + if (event->type() == QEvent::WindowBlocked) { + write(QByteArray { "1" }); + } else if (event->type() == QEvent::WindowUnblocked) { + write(QByteArray { "0" }); } } diff --git a/src/qt/qt_unixmanagerfilter.hpp b/src/qt/qt_unixmanagerfilter.hpp index 33b0f76a8..eca373b47 100644 --- a/src/qt/qt_unixmanagerfilter.hpp +++ b/src/qt/qt_unixmanagerfilter.hpp @@ -10,7 +10,7 @@ * * Authors: * Teemu Korhonen - Cacodemon345 + Cacodemon345 * * Copyright 2022 Teemu Korhonen * Copyright 2022 Cacodemon345 @@ -27,11 +27,10 @@ * Filters messages from VM-manager and * window blocked events to notify about open modal dialogs. */ -class UnixManagerSocket : public QLocalSocket -{ +class UnixManagerSocket : public QLocalSocket { Q_OBJECT public: - UnixManagerSocket(QObject* object = nullptr); + UnixManagerSocket(QObject *object = nullptr); signals: void pause(); void ctrlaltdel(); diff --git a/src/qt/qt_util.cpp b/src/qt/qt_util.cpp index 771c6d94a..876a4b047 100644 --- a/src/qt/qt_util.cpp +++ b/src/qt/qt_util.cpp @@ -19,42 +19,41 @@ #include #include #if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) -#include +# include #endif #include "qt_util.hpp" -namespace util +namespace util { +QScreen * +screenOfWidget(QWidget *widget) { - QScreen* screenOfWidget(QWidget* widget) - { #if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0) - return QApplication::screens()[QApplication::desktop()->screenNumber(widget) == -1 ? 0 : QApplication::desktop()->screenNumber(widget)]; + return QApplication::screens()[QApplication::desktop()->screenNumber(widget) == -1 ? 0 : QApplication::desktop()->screenNumber(widget)]; #else - return widget->screen(); + return widget->screen(); #endif - } +} - QString DlgFilter(std::initializer_list extensions, bool last) - { - QStringList temp; +QString +DlgFilter(std::initializer_list extensions, bool last) +{ + QStringList temp; - for (auto ext : extensions) - { + for (auto ext : extensions) { #ifdef Q_OS_UNIX - if (ext == "*") - { - temp.append("*"); - continue; - } - temp.append("*." % ext.toUpper()); -#endif - temp.append("*." % ext); + if (ext == "*") { + temp.append("*"); + continue; } + temp.append("*." % ext.toUpper()); +#endif + temp.append("*." % ext); + } #ifdef Q_OS_UNIX - temp.removeDuplicates(); + temp.removeDuplicates(); #endif - return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); - } + return " (" % temp.join(' ') % ")" % (!last ? ";;" : ""); +} } diff --git a/src/qt/qt_util.hpp b/src/qt/qt_util.hpp index 4e62c8e12..6ecd904b3 100644 --- a/src/qt/qt_util.hpp +++ b/src/qt/qt_util.hpp @@ -7,12 +7,11 @@ #include class QScreen; -namespace util -{ - /* Creates extension list for qt filedialog */ - QString DlgFilter(std::initializer_list extensions, bool last = false); - /* Returns screen the widget is on */ - QScreen* screenOfWidget(QWidget* widget); +namespace util { +/* Creates extension list for qt filedialog */ +QString DlgFilter(std::initializer_list extensions, bool last = false); +/* Returns screen the widget is on */ +QScreen *screenOfWidget(QWidget *widget); }; #endif diff --git a/src/qt/qt_vulkanrenderer.cpp b/src/qt/qt_vulkanrenderer.cpp index c62154669..41791a026 100644 --- a/src/qt/qt_vulkanrenderer.cpp +++ b/src/qt/qt_vulkanrenderer.cpp @@ -35,11 +35,10 @@ #include #include "qt_vulkanrenderer.hpp" #if QT_CONFIG(vulkan) -#include +# include -extern "C" -{ -#include <86box/86box.h> +extern "C" { +# include <86box/86box.h> } // Use a triangle strip to get a quad. @@ -58,7 +57,8 @@ static float vertexData[] = { // Y up, front = CW static const int UNIFORM_DATA_SIZE = 16 * sizeof(float); -static inline VkDeviceSize aligned(VkDeviceSize v, VkDeviceSize byteAlign) +static inline VkDeviceSize +aligned(VkDeviceSize v, VkDeviceSize byteAlign) { return (v + byteAlign - 1) & ~(byteAlign - 1); } @@ -68,7 +68,8 @@ VulkanRenderer2::VulkanRenderer2(QVulkanWindow *w) { } -VkShaderModule VulkanRenderer2::createShader(const QString &name) +VkShaderModule +VulkanRenderer2::createShader(const QString &name) { QFile file(name); if (!file.open(QIODevice::ReadOnly)) { @@ -80,11 +81,11 @@ VkShaderModule VulkanRenderer2::createShader(const QString &name) VkShaderModuleCreateInfo shaderInfo; memset(&shaderInfo, 0, sizeof(shaderInfo)); - shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shaderInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; shaderInfo.codeSize = blob.size(); - shaderInfo.pCode = reinterpret_cast(blob.constData()); + shaderInfo.pCode = reinterpret_cast(blob.constData()); VkShaderModule shaderModule; - VkResult err = m_devFuncs->vkCreateShaderModule(m_window->device(), &shaderInfo, nullptr, &shaderModule); + VkResult err = m_devFuncs->vkCreateShaderModule(m_window->device(), &shaderInfo, nullptr, &shaderModule); if (err != VK_SUCCESS) { qWarning("Failed to create shader module: %d", err); return VK_NULL_HANDLE; @@ -93,13 +94,14 @@ VkShaderModule VulkanRenderer2::createShader(const QString &name) return shaderModule; } -bool VulkanRenderer2::createTexture() +bool +VulkanRenderer2::createTexture() { QImage img(2048, 2048, QImage::Format_RGBA8888_Premultiplied); img.fill(QColor(0, 0, 0)); - QVulkanFunctions *f = m_window->vulkanInstance()->functions(); - VkDevice dev = m_window->device(); + QVulkanFunctions *f = m_window->vulkanInstance()->functions(); + VkDevice dev = m_window->device(); m_texFormat = VK_FORMAT_B8G8R8A8_UNORM; @@ -108,7 +110,7 @@ bool VulkanRenderer2::createTexture() // tiling format. VkFormatProperties props; f->vkGetPhysicalDeviceFormatProperties(m_window->physicalDevice(), m_texFormat, &props); - const bool canSampleLinear = (props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); + const bool canSampleLinear = (props.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); const bool canSampleOptimal = (props.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT); if (!canSampleLinear && !canSampleOptimal) { qWarning("Neither linear nor optimal image sampling is supported for RGBA8"); @@ -146,14 +148,14 @@ bool VulkanRenderer2::createTexture() VkImageViewCreateInfo viewInfo; memset(&viewInfo, 0, sizeof(viewInfo)); - viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - viewInfo.image = m_texImage; - viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; - viewInfo.format = m_texFormat; - viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; - viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; - viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; - viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; + viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + viewInfo.image = m_texImage; + viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; + viewInfo.format = m_texFormat; + viewInfo.components.r = VK_COMPONENT_SWIZZLE_R; + viewInfo.components.g = VK_COMPONENT_SWIZZLE_G; + viewInfo.components.b = VK_COMPONENT_SWIZZLE_B; + viewInfo.components.a = VK_COMPONENT_SWIZZLE_A; viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; viewInfo.subresourceRange.levelCount = viewInfo.subresourceRange.layerCount = 1; @@ -168,24 +170,25 @@ bool VulkanRenderer2::createTexture() return true; } -bool VulkanRenderer2::createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, - VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex) +bool +VulkanRenderer2::createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, + VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex) { VkDevice dev = m_window->device(); VkImageCreateInfo imageInfo; memset(&imageInfo, 0, sizeof(imageInfo)); - imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - imageInfo.imageType = VK_IMAGE_TYPE_2D; - imageInfo.format = m_texFormat; - imageInfo.extent.width = size.width(); + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = VK_IMAGE_TYPE_2D; + imageInfo.format = m_texFormat; + imageInfo.extent.width = size.width(); imageInfo.extent.height = size.height(); - imageInfo.extent.depth = 1; - imageInfo.mipLevels = 1; - imageInfo.arrayLayers = 1; - imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; - imageInfo.tiling = tiling; - imageInfo.usage = usage; + imageInfo.extent.depth = 1; + imageInfo.mipLevels = 1; + imageInfo.arrayLayers = 1; + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + imageInfo.tiling = tiling; + imageInfo.usage = usage; imageInfo.initialLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; VkResult err = m_devFuncs->vkCreateImage(dev, &imageInfo, nullptr, image); @@ -230,7 +233,8 @@ bool VulkanRenderer2::createTextureImage(const QSize &size, VkImage *image, VkDe return true; } -bool VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory) +bool +VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory) { VkDevice dev = m_window->device(); @@ -242,7 +246,7 @@ bool VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDevic VkSubresourceLayout layout; m_devFuncs->vkGetImageSubresourceLayout(dev, image, &subres, &layout); - uchar *p; + uchar *p; VkResult err = m_devFuncs->vkMapMemory(dev, memory, layout.offset, layout.size, 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) { qWarning("Failed to map memory for linear image: %d", err); @@ -259,7 +263,8 @@ bool VulkanRenderer2::writeLinearImage(const QImage &img, VkImage image, VkDevic return true; } -void VulkanRenderer2::ensureTexture() +void +VulkanRenderer2::ensureTexture() { if (!m_texLayoutPending && !m_texStagingPending) return; @@ -269,24 +274,24 @@ void VulkanRenderer2::ensureTexture() VkImageMemoryBarrier barrier; memset(&barrier, 0, sizeof(barrier)); - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.levelCount = barrier.subresourceRange.layerCount = 1; if (m_texLayoutPending) { m_texLayoutPending = false; - barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.image = m_texImage; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); VkDevice dev = m_window->device(); @@ -301,38 +306,38 @@ void VulkanRenderer2::ensureTexture() VkResult err = m_devFuncs->vkMapMemory(dev, m_texMem, layout.offset, layout.size, 0, reinterpret_cast(&mappedPtr)); if (err != VK_SUCCESS) { qWarning("Failed to map memory for linear image: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } imagePitch = layout.rowPitch; - if (qobject_cast(m_window)) { - emit qobject_cast(m_window)->rendererInitialized(); + if (qobject_cast(m_window)) { + emit qobject_cast(m_window)->rendererInitialized(); } } else { m_texStagingPending = false; if (!m_texStagingTransferLayout) { - barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; - barrier.image = m_texStaging; + barrier.image = m_texStaging; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_HOST_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_HOST_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); - barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_PREINITIALIZED; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; barrier.srcAccessMask = 0; barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.image = m_texImage; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); VkDevice dev = m_window->device(); @@ -347,12 +352,12 @@ void VulkanRenderer2::ensureTexture() VkResult err = m_devFuncs->vkMapMemory(dev, m_texStagingMem, layout.offset, layout.size, 0, reinterpret_cast(&mappedPtr)); if (err != VK_SUCCESS) { qWarning("Failed to map memory for linear image: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } imagePitch = layout.rowPitch; - if (qobject_cast(m_window)) { - emit qobject_cast(m_window)->rendererInitialized(); + if (qobject_cast(m_window)) { + emit qobject_cast(m_window)->rendererInitialized(); } m_texStagingTransferLayout = true; @@ -364,26 +369,27 @@ void VulkanRenderer2::ensureTexture() copyInfo.srcSubresource.layerCount = 1; copyInfo.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; copyInfo.dstSubresource.layerCount = 1; - copyInfo.extent.width = m_texSize.width(); - copyInfo.extent.height = m_texSize.height(); - copyInfo.extent.depth = 1; + copyInfo.extent.width = m_texSize.width(); + copyInfo.extent.height = m_texSize.height(); + copyInfo.extent.depth = 1; m_devFuncs->vkCmdCopyImage(cb, m_texStaging, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - m_texImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Info); + m_texImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Info); - barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.image = m_texImage; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); } } -void VulkanRenderer2::updateSamplers() +void +VulkanRenderer2::updateSamplers() { static int cur_video_filter_method = -1; @@ -400,52 +406,53 @@ void VulkanRenderer2::updateSamplers() for (int i = 0; i < m_window->concurrentFrameCount(); i++) { VkWriteDescriptorSet descWrite[2]; memset(descWrite, 0, sizeof(descWrite)); - descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[0].dstSet = m_descSet[i]; - descWrite[0].dstBinding = 0; + descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[0].dstSet = m_descSet[i]; + descWrite[0].dstBinding = 0; descWrite[0].descriptorCount = 1; - descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; + descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; - descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[1].dstSet = m_descSet[i]; - descWrite[1].dstBinding = 1; + descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[1].dstSet = m_descSet[i]; + descWrite[1].dstBinding = 1; descWrite[1].descriptorCount = 1; - descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descWrite[1].pImageInfo = &descImageInfo; + descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descWrite[1].pImageInfo = &descImageInfo; m_devFuncs->vkUpdateDescriptorSets(m_window->device(), 2, descWrite, 0, nullptr); } } } -void VulkanRenderer2::initResources() +void +VulkanRenderer2::initResources() { qDebug("initResources"); VkDevice dev = m_window->device(); - m_devFuncs = m_window->vulkanInstance()->deviceFunctions(dev); + m_devFuncs = m_window->vulkanInstance()->deviceFunctions(dev); // The setup is similar to hellovulkantriangle. The difference is the // presence of a second vertex attribute (texcoord), a sampler, and that we // need blending. - const int concurrentFrameCount = m_window->concurrentFrameCount(); - const VkPhysicalDeviceLimits *pdevLimits = &m_window->physicalDeviceProperties()->limits; - const VkDeviceSize uniAlign = pdevLimits->minUniformBufferOffsetAlignment; + const int concurrentFrameCount = m_window->concurrentFrameCount(); + const VkPhysicalDeviceLimits *pdevLimits = &m_window->physicalDeviceProperties()->limits; + const VkDeviceSize uniAlign = pdevLimits->minUniformBufferOffsetAlignment; qDebug("uniform buffer offset alignment is %u", (uint) uniAlign); VkBufferCreateInfo bufInfo; memset(&bufInfo, 0, sizeof(bufInfo)); bufInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; // Our internal layout is vertex, uniform, uniform, ... with each uniform buffer start offset aligned to uniAlign. - const VkDeviceSize vertexAllocSize = aligned(sizeof(vertexData), uniAlign); + const VkDeviceSize vertexAllocSize = aligned(sizeof(vertexData), uniAlign); const VkDeviceSize uniformAllocSize = aligned(UNIFORM_DATA_SIZE, uniAlign); - bufInfo.size = vertexAllocSize + concurrentFrameCount * uniformAllocSize; - bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; + bufInfo.size = vertexAllocSize + concurrentFrameCount * uniformAllocSize; + bufInfo.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; VkResult err = m_devFuncs->vkCreateBuffer(dev, &bufInfo, nullptr, &m_buf); if (err != VK_SUCCESS) { qWarning("Failed to create buffer: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } VkMemoryRequirements memReq; @@ -461,20 +468,20 @@ void VulkanRenderer2::initResources() err = m_devFuncs->vkAllocateMemory(dev, &memAllocInfo, nullptr, &m_bufMem); if (err != VK_SUCCESS) { qWarning("Failed to allocate memory: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } err = m_devFuncs->vkBindBufferMemory(dev, m_buf, m_bufMem, 0); if (err != VK_SUCCESS) { qWarning("Failed to bind buffer memory: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } quint8 *p; err = m_devFuncs->vkMapMemory(dev, m_bufMem, 0, memReq.size, 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) { qWarning("Failed to map memory: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } memcpy(p, vertexData, sizeof(vertexData)); QMatrix4x4 ident; @@ -484,7 +491,7 @@ void VulkanRenderer2::initResources() memcpy(p + offset, ident.constData(), 16 * sizeof(float)); m_uniformBufInfo[i].buffer = m_buf; m_uniformBufInfo[i].offset = offset; - m_uniformBufInfo[i].range = uniformAllocSize; + m_uniformBufInfo[i].range = uniformAllocSize; } m_devFuncs->vkUnmapMemory(dev, m_bufMem); @@ -494,93 +501,86 @@ void VulkanRenderer2::initResources() VK_VERTEX_INPUT_RATE_VERTEX }; VkVertexInputAttributeDescription vertexAttrDesc[] = { - { // position - 0, // location - 0, // binding - VK_FORMAT_R32G32B32_SFLOAT, - 0 - }, + {// position + 0, // location + 0, // binding + VK_FORMAT_R32G32B32_SFLOAT, + 0 }, { // texcoord - 1, - 0, - VK_FORMAT_R32G32_SFLOAT, - 3 * sizeof(float) - } + 1, + 0, + VK_FORMAT_R32G32_SFLOAT, + 3 * sizeof(float)} }; VkPipelineVertexInputStateCreateInfo vertexInputInfo; - vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; - vertexInputInfo.pNext = nullptr; - vertexInputInfo.flags = 0; - vertexInputInfo.vertexBindingDescriptionCount = 1; - vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDesc; + vertexInputInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; + vertexInputInfo.pNext = nullptr; + vertexInputInfo.flags = 0; + vertexInputInfo.vertexBindingDescriptionCount = 1; + vertexInputInfo.pVertexBindingDescriptions = &vertexBindingDesc; vertexInputInfo.vertexAttributeDescriptionCount = 2; - vertexInputInfo.pVertexAttributeDescriptions = vertexAttrDesc; + vertexInputInfo.pVertexAttributeDescriptions = vertexAttrDesc; // Sampler. VkSamplerCreateInfo samplerInfo; memset(&samplerInfo, 0, sizeof(samplerInfo)); - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.magFilter = VK_FILTER_NEAREST; - samplerInfo.minFilter = VK_FILTER_NEAREST; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.magFilter = VK_FILTER_NEAREST; + samplerInfo.minFilter = VK_FILTER_NEAREST; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; samplerInfo.maxAnisotropy = 1.0f; - samplerInfo.maxLod = 0.25; - err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_sampler); + samplerInfo.maxLod = 0.25; + err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_sampler); if (err != VK_SUCCESS) { qWarning("Failed to create sampler: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } samplerInfo.magFilter = VK_FILTER_LINEAR; samplerInfo.minFilter = VK_FILTER_LINEAR; - err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_linearSampler); + err = m_devFuncs->vkCreateSampler(dev, &samplerInfo, nullptr, &m_linearSampler); if (err != VK_SUCCESS) { qWarning("Failed to create sampler: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Texture. if (!createTexture()) { qWarning("Failed to create texture"); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Set up descriptor set and its layout. VkDescriptorPoolSize descPoolSizes[2] = { - { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount) }, - { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32_t(concurrentFrameCount) } + {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, uint32_t(concurrentFrameCount)}, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, uint32_t(concurrentFrameCount)} }; VkDescriptorPoolCreateInfo descPoolInfo; memset(&descPoolInfo, 0, sizeof(descPoolInfo)); - descPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; - descPoolInfo.maxSets = concurrentFrameCount; + descPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + descPoolInfo.maxSets = concurrentFrameCount; descPoolInfo.poolSizeCount = 2; - descPoolInfo.pPoolSizes = descPoolSizes; - err = m_devFuncs->vkCreateDescriptorPool(dev, &descPoolInfo, nullptr, &m_descPool); + descPoolInfo.pPoolSizes = descPoolSizes; + err = m_devFuncs->vkCreateDescriptorPool(dev, &descPoolInfo, nullptr, &m_descPool); if (err != VK_SUCCESS) { qWarning("Failed to create descriptor pool: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } - VkDescriptorSetLayoutBinding layoutBinding[2] = - { - { - 0, // binding - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - 1, // descriptorCount - VK_SHADER_STAGE_VERTEX_BIT, - nullptr - }, - { - 1, // binding - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - 1, // descriptorCount - VK_SHADER_STAGE_FRAGMENT_BIT, - nullptr - } + VkDescriptorSetLayoutBinding layoutBinding[2] = { + {0, // binding + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + 1, // descriptorCount + VK_SHADER_STAGE_VERTEX_BIT, + nullptr}, + { 1, // binding + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + 1, // descriptorCount + VK_SHADER_STAGE_FRAGMENT_BIT, + nullptr} }; VkDescriptorSetLayoutCreateInfo descLayoutInfo = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, @@ -592,7 +592,7 @@ void VulkanRenderer2::initResources() err = m_devFuncs->vkCreateDescriptorSetLayout(dev, &descLayoutInfo, nullptr, &m_descSetLayout); if (err != VK_SUCCESS) { qWarning("Failed to create descriptor set layout: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } for (int i = 0; i < concurrentFrameCount; ++i) { @@ -606,17 +606,17 @@ void VulkanRenderer2::initResources() err = m_devFuncs->vkAllocateDescriptorSets(dev, &descSetAllocInfo, &m_descSet[i]); if (err != VK_SUCCESS) { qWarning("Failed to allocate descriptor set: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } VkWriteDescriptorSet descWrite[2]; memset(descWrite, 0, sizeof(descWrite)); - descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[0].dstSet = m_descSet[i]; - descWrite[0].dstBinding = 0; + descWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[0].dstSet = m_descSet[i]; + descWrite[0].dstBinding = 0; descWrite[0].descriptorCount = 1; - descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; + descWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + descWrite[0].pBufferInfo = &m_uniformBufInfo[i]; VkDescriptorImageInfo descImageInfo = { video_filter_method == 1 ? m_linearSampler : m_sampler, @@ -624,12 +624,12 @@ void VulkanRenderer2::initResources() VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }; - descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - descWrite[1].dstSet = m_descSet[i]; - descWrite[1].dstBinding = 1; + descWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + descWrite[1].dstSet = m_descSet[i]; + descWrite[1].dstBinding = 1; descWrite[1].descriptorCount = 1; - descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - descWrite[1].pImageInfo = &descImageInfo; + descWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + descWrite[1].pImageInfo = &descImageInfo; m_devFuncs->vkUpdateDescriptorSets(dev, 2, descWrite, 0, nullptr); } @@ -638,60 +638,60 @@ void VulkanRenderer2::initResources() VkPipelineCacheCreateInfo pipelineCacheInfo; memset(&pipelineCacheInfo, 0, sizeof(pipelineCacheInfo)); pipelineCacheInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; - err = m_devFuncs->vkCreatePipelineCache(dev, &pipelineCacheInfo, nullptr, &m_pipelineCache); + err = m_devFuncs->vkCreatePipelineCache(dev, &pipelineCacheInfo, nullptr, &m_pipelineCache); if (err != VK_SUCCESS) { qWarning("Failed to create pipeline cache: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Pipeline layout VkPipelineLayoutCreateInfo pipelineLayoutInfo; memset(&pipelineLayoutInfo, 0, sizeof(pipelineLayoutInfo)); - pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; pipelineLayoutInfo.setLayoutCount = 1; - pipelineLayoutInfo.pSetLayouts = &m_descSetLayout; - err = m_devFuncs->vkCreatePipelineLayout(dev, &pipelineLayoutInfo, nullptr, &m_pipelineLayout); + pipelineLayoutInfo.pSetLayouts = &m_descSetLayout; + err = m_devFuncs->vkCreatePipelineLayout(dev, &pipelineLayoutInfo, nullptr, &m_pipelineLayout); if (err != VK_SUCCESS) { qWarning("Failed to create pipeline layout: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } // Shaders -/* -#version 440 + /* + #version 440 -layout(location = 0) in vec4 position; -layout(location = 1) in vec2 texcoord; + layout(location = 0) in vec4 position; + layout(location = 1) in vec2 texcoord; -layout(location = 0) out vec2 v_texcoord; + layout(location = 0) out vec2 v_texcoord; -layout(std140, binding = 0) uniform buf { - mat4 mvp; -} ubuf; + layout(std140, binding = 0) uniform buf { + mat4 mvp; + } ubuf; -out gl_PerVertex { vec4 gl_Position; }; + out gl_PerVertex { vec4 gl_Position; }; -void main() -{ - v_texcoord = texcoord; - gl_Position = ubuf.mvp * position; -} -*/ + void main() + { + v_texcoord = texcoord; + gl_Position = ubuf.mvp * position; + } + */ VkShaderModule vertShaderModule = createShader(QStringLiteral(":/texture_vert.spv")); -/* -#version 440 + /* + #version 440 -layout(location = 0) in vec2 v_texcoord; + layout(location = 0) in vec2 v_texcoord; -layout(location = 0) out vec4 fragColor; + layout(location = 0) out vec4 fragColor; -layout(binding = 1) uniform sampler2D tex; + layout(binding = 1) uniform sampler2D tex; -void main() -{ - fragColor = texture(tex, v_texcoord); -} -*/ + void main() + { + fragColor = texture(tex, v_texcoord); + } + */ VkShaderModule fragShaderModule = createShader(QStringLiteral(":/texture_frag.spv")); // Graphics pipeline @@ -720,46 +720,46 @@ void main() } }; pipelineInfo.stageCount = 2; - pipelineInfo.pStages = shaderStages; + pipelineInfo.pStages = shaderStages; pipelineInfo.pVertexInputState = &vertexInputInfo; VkPipelineInputAssemblyStateCreateInfo ia; memset(&ia, 0, sizeof(ia)); - ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; - ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; + ia.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; + ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; pipelineInfo.pInputAssemblyState = &ia; // The viewport and scissor will be set dynamically via vkCmdSetViewport/Scissor. // This way the pipeline does not need to be touched when resizing the window. VkPipelineViewportStateCreateInfo vp; memset(&vp, 0, sizeof(vp)); - vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; - vp.viewportCount = 1; - vp.scissorCount = 1; + vp.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; + vp.viewportCount = 1; + vp.scissorCount = 1; pipelineInfo.pViewportState = &vp; VkPipelineRasterizationStateCreateInfo rs; memset(&rs, 0, sizeof(rs)); - rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; - rs.polygonMode = VK_POLYGON_MODE_FILL; - rs.cullMode = VK_CULL_MODE_BACK_BIT; - rs.frontFace = VK_FRONT_FACE_CLOCKWISE; - rs.lineWidth = 1.0f; + rs.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; + rs.polygonMode = VK_POLYGON_MODE_FILL; + rs.cullMode = VK_CULL_MODE_BACK_BIT; + rs.frontFace = VK_FRONT_FACE_CLOCKWISE; + rs.lineWidth = 1.0f; pipelineInfo.pRasterizationState = &rs; VkPipelineMultisampleStateCreateInfo ms; memset(&ms, 0, sizeof(ms)); - ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; + ms.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; pipelineInfo.pMultisampleState = &ms; VkPipelineDepthStencilStateCreateInfo ds; memset(&ds, 0, sizeof(ds)); - ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - ds.depthTestEnable = VK_TRUE; - ds.depthWriteEnable = VK_TRUE; - ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; + ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; + ds.depthTestEnable = VK_TRUE; + ds.depthWriteEnable = VK_TRUE; + ds.depthCompareOp = VK_COMPARE_OP_LESS_OR_EQUAL; pipelineInfo.pDepthStencilState = &ds; VkPipelineColorBlendStateCreateInfo cb; @@ -768,33 +768,33 @@ void main() // assume pre-multiplied alpha, blend, write out all of rgba VkPipelineColorBlendAttachmentState att; memset(&att, 0, sizeof(att)); - att.colorWriteMask = 0xF; - att.blendEnable = VK_TRUE; - att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; - att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - att.colorBlendOp = VK_BLEND_OP_ADD; - att.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; - att.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - att.alphaBlendOp = VK_BLEND_OP_ADD; - cb.attachmentCount = 1; - cb.pAttachments = &att; + att.colorWriteMask = 0xF; + att.blendEnable = VK_TRUE; + att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; + att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + att.colorBlendOp = VK_BLEND_OP_ADD; + att.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; + att.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + att.alphaBlendOp = VK_BLEND_OP_ADD; + cb.attachmentCount = 1; + cb.pAttachments = &att; pipelineInfo.pColorBlendState = &cb; - VkDynamicState dynEnable[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkDynamicState dynEnable[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; VkPipelineDynamicStateCreateInfo dyn; memset(&dyn, 0, sizeof(dyn)); - dyn.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; - dyn.dynamicStateCount = sizeof(dynEnable) / sizeof(VkDynamicState); - dyn.pDynamicStates = dynEnable; + dyn.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; + dyn.dynamicStateCount = sizeof(dynEnable) / sizeof(VkDynamicState); + dyn.pDynamicStates = dynEnable; pipelineInfo.pDynamicState = &dyn; - pipelineInfo.layout = m_pipelineLayout; + pipelineInfo.layout = m_pipelineLayout; pipelineInfo.renderPass = m_window->defaultRenderPass(); err = m_devFuncs->vkCreateGraphicsPipelines(dev, m_pipelineCache, 1, &pipelineInfo, nullptr, &m_pipeline); if (err != VK_SUCCESS) { qWarning("Failed to create graphics pipeline: %d", err); - return emit qobject_cast(m_window)->errorInitializing(); + return emit qobject_cast(m_window)->errorInitializing(); } if (vertShaderModule) @@ -807,7 +807,8 @@ void main() pclog("Vulkan driver version: %d.%d.%d\n", VK_VERSION_MAJOR(m_window->physicalDeviceProperties()->driverVersion), VK_VERSION_MINOR(m_window->physicalDeviceProperties()->driverVersion), VK_VERSION_PATCH(m_window->physicalDeviceProperties()->driverVersion)); } -void VulkanRenderer2::initSwapChainResources() +void +VulkanRenderer2::initSwapChainResources() { qDebug("initSwapChainResources"); @@ -815,12 +816,14 @@ void VulkanRenderer2::initSwapChainResources() m_proj = m_window->clipCorrectionMatrix(); // adjust for Vulkan-OpenGL clip space differences } -void VulkanRenderer2::releaseSwapChainResources() +void +VulkanRenderer2::releaseSwapChainResources() { qDebug("releaseSwapChainResources"); } -void VulkanRenderer2::releaseResources() +void +VulkanRenderer2::releaseResources() { qDebug("releaseResources"); @@ -897,85 +900,88 @@ void VulkanRenderer2::releaseResources() } } -void VulkanRenderer2::startNextFrame() +void +VulkanRenderer2::startNextFrame() { - VkDevice dev = m_window->device(); - VkCommandBuffer cb = m_window->currentCommandBuffer(); - const QSize sz = m_window->swapChainImageSize(); + VkDevice dev = m_window->device(); + VkCommandBuffer cb = m_window->currentCommandBuffer(); + const QSize sz = m_window->swapChainImageSize(); updateSamplers(); // Add the necessary barriers and do the host-linear -> device-optimal copy, if not yet done. ensureTexture(); - VkClearColorValue clearColor = {{ 0, 0, 0, 1 }}; + VkClearColorValue clearColor = { + {0, 0, 0, 1} + }; VkClearDepthStencilValue clearDS = { 1, 0 }; - VkClearValue clearValues[2]; + VkClearValue clearValues[2]; memset(clearValues, 0, sizeof(clearValues)); - clearValues[0].color = clearColor; + clearValues[0].color = clearColor; clearValues[1].depthStencil = clearDS; VkRenderPassBeginInfo rpBeginInfo; memset(&rpBeginInfo, 0, sizeof(rpBeginInfo)); - rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - rpBeginInfo.renderPass = m_window->defaultRenderPass(); - rpBeginInfo.framebuffer = m_window->currentFramebuffer(); - rpBeginInfo.renderArea.extent.width = sz.width(); + rpBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + rpBeginInfo.renderPass = m_window->defaultRenderPass(); + rpBeginInfo.framebuffer = m_window->currentFramebuffer(); + rpBeginInfo.renderArea.extent.width = sz.width(); rpBeginInfo.renderArea.extent.height = sz.height(); - rpBeginInfo.clearValueCount = 2; - rpBeginInfo.pClearValues = clearValues; - VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); + rpBeginInfo.clearValueCount = 2; + rpBeginInfo.pClearValues = clearValues; + VkCommandBuffer cmdBuf = m_window->currentCommandBuffer(); m_devFuncs->vkCmdBeginRenderPass(cmdBuf, &rpBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - quint8 *p; + quint8 *p; VkResult err = m_devFuncs->vkMapMemory(dev, m_bufMem, m_uniformBufInfo[m_window->currentFrame()].offset, - UNIFORM_DATA_SIZE, 0, reinterpret_cast(&p)); + UNIFORM_DATA_SIZE, 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) qFatal("Failed to map memory: %d", err); QMatrix4x4 m = m_proj; - //m.rotate(m_rotation, 0, 0, 1); + // m.rotate(m_rotation, 0, 0, 1); memcpy(p, m.constData(), 16 * sizeof(float)); m_devFuncs->vkUnmapMemory(dev, m_bufMem); p = nullptr; // Second pass for texture coordinates. err = m_devFuncs->vkMapMemory(dev, m_bufMem, 0, - sizeof(vertexData), 0, reinterpret_cast(&p)); + sizeof(vertexData), 0, reinterpret_cast(&p)); if (err != VK_SUCCESS) qFatal("Failed to map memory: %d", err); - float* floatData = (float*)p; - auto source = qobject_cast(m_window)->source; - auto destination = qobject_cast(m_window)->destination; - floatData[3] = (float)source.x() / 2048.f; - floatData[9] = (float)(source.y()) / 2048.f; - floatData[8] = (float)source.x() / 2048.f; - floatData[4] = (float)(source.y() + source.height()) / 2048.f; - floatData[13] = (float)(source.x() + source.width()) / 2048.f; - floatData[19] = (float)(source.y()) / 2048.f; - floatData[18] = (float)(source.x() + source.width()) / 2048.f; - floatData[14] = (float)(source.y() + source.height()) / 2048.f; + float *floatData = (float *) p; + auto source = qobject_cast(m_window)->source; + auto destination = qobject_cast(m_window)->destination; + floatData[3] = (float) source.x() / 2048.f; + floatData[9] = (float) (source.y()) / 2048.f; + floatData[8] = (float) source.x() / 2048.f; + floatData[4] = (float) (source.y() + source.height()) / 2048.f; + floatData[13] = (float) (source.x() + source.width()) / 2048.f; + floatData[19] = (float) (source.y()) / 2048.f; + floatData[18] = (float) (source.x() + source.width()) / 2048.f; + floatData[14] = (float) (source.y() + source.height()) / 2048.f; m_devFuncs->vkUnmapMemory(dev, m_bufMem); m_devFuncs->vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipeline); m_devFuncs->vkCmdBindDescriptorSets(cb, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, - &m_descSet[m_window->currentFrame()], 0, nullptr); + &m_descSet[m_window->currentFrame()], 0, nullptr); VkDeviceSize vbOffset = 0; m_devFuncs->vkCmdBindVertexBuffers(cb, 0, 1, &m_buf, &vbOffset); VkViewport viewport; - viewport.x = destination.x() * m_window->devicePixelRatio(); - viewport.y = destination.y() * m_window->devicePixelRatio(); - viewport.width = destination.width() * m_window->devicePixelRatio(); - viewport.height = destination.height() * m_window->devicePixelRatio(); + viewport.x = destination.x() * m_window->devicePixelRatio(); + viewport.y = destination.y() * m_window->devicePixelRatio(); + viewport.width = destination.width() * m_window->devicePixelRatio(); + viewport.height = destination.height() * m_window->devicePixelRatio(); viewport.minDepth = 0; viewport.maxDepth = 1; m_devFuncs->vkCmdSetViewport(cb, 0, 1, &viewport); VkRect2D scissor; - scissor.offset.x = viewport.x; - scissor.offset.y = viewport.y; - scissor.extent.width = viewport.width; + scissor.offset.x = viewport.x; + scissor.offset.y = viewport.y; + scissor.extent.width = viewport.width; scissor.extent.height = viewport.height; m_devFuncs->vkCmdSetScissor(cb, 0, 1, &scissor); @@ -984,20 +990,20 @@ void VulkanRenderer2::startNextFrame() m_devFuncs->vkCmdEndRenderPass(cmdBuf); if (m_texStagingTransferLayout) { - VkImageMemoryBarrier barrier{}; - barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + VkImageMemoryBarrier barrier {}; + barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; barrier.subresourceRange.levelCount = barrier.subresourceRange.layerCount = 1; - barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; - barrier.image = m_texImage; + barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + barrier.oldLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + barrier.srcAccessMask = VK_ACCESS_SHADER_READ_BIT; + barrier.image = m_texImage; m_devFuncs->vkCmdPipelineBarrier(cb, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, - 1, &barrier); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, + 1, &barrier); m_texStagingPending = true; } diff --git a/src/qt/qt_vulkanrenderer.hpp b/src/qt/qt_vulkanrenderer.hpp index abd4d7a13..7961dd7f9 100644 --- a/src/qt/qt_vulkanrenderer.hpp +++ b/src/qt/qt_vulkanrenderer.hpp @@ -36,12 +36,11 @@ #include #if QT_CONFIG(vulkan) -#include "qt_vulkanwindowrenderer.hpp" +# include "qt_vulkanwindowrenderer.hpp" -class VulkanRenderer2 : public QVulkanWindowRenderer -{ +class VulkanRenderer2 : public QVulkanWindowRenderer { public: - void* mappedPtr = nullptr; + void *mappedPtr = nullptr; size_t imagePitch = 2048 * 4; VulkanRenderer2(QVulkanWindow *w); @@ -54,42 +53,42 @@ public: private: VkShaderModule createShader(const QString &name); - bool createTexture(); - bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, - VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); - bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); - void ensureTexture(); - void updateSamplers(); + bool createTexture(); + bool createTextureImage(const QSize &size, VkImage *image, VkDeviceMemory *mem, + VkImageTiling tiling, VkImageUsageFlags usage, uint32_t memIndex); + bool writeLinearImage(const QImage &img, VkImage image, VkDeviceMemory memory); + void ensureTexture(); + void updateSamplers(); - QVulkanWindow *m_window; + QVulkanWindow *m_window; QVulkanDeviceFunctions *m_devFuncs; - VkDeviceMemory m_bufMem = VK_NULL_HANDLE; - VkBuffer m_buf = VK_NULL_HANDLE; + VkDeviceMemory m_bufMem = VK_NULL_HANDLE; + VkBuffer m_buf = VK_NULL_HANDLE; VkDescriptorBufferInfo m_uniformBufInfo[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - VkDescriptorPool m_descPool = VK_NULL_HANDLE; + VkDescriptorPool m_descPool = VK_NULL_HANDLE; VkDescriptorSetLayout m_descSetLayout = VK_NULL_HANDLE; - VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; + VkDescriptorSet m_descSet[QVulkanWindow::MAX_CONCURRENT_FRAME_COUNT]; - VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; + VkPipelineCache m_pipelineCache = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; - VkPipeline m_pipeline = VK_NULL_HANDLE; + VkPipeline m_pipeline = VK_NULL_HANDLE; - VkSampler m_sampler = VK_NULL_HANDLE; - VkSampler m_linearSampler = VK_NULL_HANDLE; - VkImage m_texImage = VK_NULL_HANDLE; - VkDeviceMemory m_texMem = VK_NULL_HANDLE; - bool m_texLayoutPending = false; - VkImageView m_texView = VK_NULL_HANDLE; - VkImage m_texStaging = VK_NULL_HANDLE; - VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; - bool m_texStagingPending = false; - bool m_texStagingTransferLayout = false; - QSize m_texSize; - VkFormat m_texFormat; + VkSampler m_sampler = VK_NULL_HANDLE; + VkSampler m_linearSampler = VK_NULL_HANDLE; + VkImage m_texImage = VK_NULL_HANDLE; + VkDeviceMemory m_texMem = VK_NULL_HANDLE; + bool m_texLayoutPending = false; + VkImageView m_texView = VK_NULL_HANDLE; + VkImage m_texStaging = VK_NULL_HANDLE; + VkDeviceMemory m_texStagingMem = VK_NULL_HANDLE; + bool m_texStagingPending = false; + bool m_texStagingTransferLayout = false; + QSize m_texSize; + VkFormat m_texFormat; QMatrix4x4 m_proj; - float m_rotation = 0.0f; + float m_rotation = 0.0f; }; #endif diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index ba32d6e9b..60ad5be96 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -4,20 +4,19 @@ #include #if QT_CONFIG(vulkan) -#include -#include -#include -#include +# include +# include +# include +# include -#include "qt_mainwindow.hpp" -#include "qt_vulkanrenderer.hpp" +# include "qt_mainwindow.hpp" +# include "qt_vulkanrenderer.hpp" -extern "C" -{ -#include <86box/86box.h> -#include <86box/video.h> +extern "C" { +# include <86box/86box.h> +# include <86box/video.h> } -#if 0 +# if 0 extern MainWindow* main_window; /* #version 450 @@ -695,10 +694,10 @@ public: return "VK_ERROR_VALIDATION_FAILED_EXT"; case VK_ERROR_INVALID_SHADER_NV: return "VK_ERROR_INVALID_SHADER_NV"; -#if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 +# if VK_HEADER_VERSION >= 135 && VK_HEADER_VERSION < 162 case VK_ERROR_INCOMPATIBLE_VERSION_KHR: return "VK_ERROR_INCOMPATIBLE_VERSION_KHR"; -#endif +# endif case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: return "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; case VK_ERROR_NOT_PERMITTED_EXT: @@ -789,9 +788,9 @@ public: m_devFuncs->vkDeviceWaitIdle(m_window->device()); } }; -#endif +# endif -VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent) +VulkanWindowRenderer::VulkanWindowRenderer(QWidget *parent) : QVulkanWindow(parent->windowHandle()) { parentWidget = parent; @@ -799,47 +798,57 @@ VulkanWindowRenderer::VulkanWindowRenderer(QWidget* parent) instance.create(); setVulkanInstance(&instance); setPhysicalDeviceIndex(0); - setPreferredColorFormats({VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A8B8G8R8_UNORM_PACK32}); + setPreferredColorFormats({ VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_A8B8G8R8_UNORM_PACK32 }); setFlags(Flag::PersistentResources); buf_usage = std::vector(1); buf_usage[0].clear(); } -QVulkanWindowRenderer* VulkanWindowRenderer::createRenderer() +QVulkanWindowRenderer * +VulkanWindowRenderer::createRenderer() { renderer = new VulkanRenderer2(this); return renderer; } -void VulkanWindowRenderer::resizeEvent(QResizeEvent *event) { +void +VulkanWindowRenderer::resizeEvent(QResizeEvent *event) +{ onResize(width(), height()); QVulkanWindow::resizeEvent(event); } -bool VulkanWindowRenderer::event(QEvent *event) +bool +VulkanWindowRenderer::event(QEvent *event) { bool res = false; - if (!eventDelegate(event, res)) return QVulkanWindow::event(event); + if (!eventDelegate(event, res)) + return QVulkanWindow::event(event); return res; } -void VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) +void +VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) { auto origSource = source; source.setRect(x, y, w, h); - if (isExposed()) requestUpdate(); + if (isExposed()) + requestUpdate(); buf_usage[0].clear(); - if (origSource != source) onResize(this->width(), this->height()); + if (origSource != source) + onResize(this->width(), this->height()); } -uint32_t VulkanWindowRenderer::getBytesPerRow() +uint32_t +VulkanWindowRenderer::getBytesPerRow() { return renderer->imagePitch; } -std::vector> VulkanWindowRenderer::getBuffers() +std::vector> +VulkanWindowRenderer::getBuffers() { - return std::vector{std::make_tuple((uint8_t*)renderer->mappedPtr, &this->buf_usage[0])}; + return std::vector { std::make_tuple((uint8_t *) renderer->mappedPtr, &this->buf_usage[0]) }; } #endif diff --git a/src/qt/qt_vulkanwindowrenderer.hpp b/src/qt/qt_vulkanwindowrenderer.hpp index df252d393..828d091e6 100644 --- a/src/qt/qt_vulkanwindowrenderer.hpp +++ b/src/qt/qt_vulkanwindowrenderer.hpp @@ -4,35 +4,36 @@ #include #if QT_CONFIG(vulkan) -#include "qt_renderercommon.hpp" -#include "qt_vulkanrenderer.hpp" +# include "qt_renderercommon.hpp" +# include "qt_vulkanrenderer.hpp" class VulkanRenderer2; -class VulkanWindowRenderer : public QVulkanWindow, public RendererCommon -{ +class VulkanWindowRenderer : public QVulkanWindow, public RendererCommon { Q_OBJECT public: - VulkanWindowRenderer(QWidget* parent); + VulkanWindowRenderer(QWidget *parent); public slots: void onBlit(int buf_idx, int x, int y, int w, int h); signals: void rendererInitialized(); void errorInitializing(); + protected: virtual std::vector> getBuffers() override; - void resizeEvent(QResizeEvent*) override; - bool event(QEvent*) override; - uint32_t getBytesPerRow() override; + void resizeEvent(QResizeEvent *) override; + bool event(QEvent *) override; + uint32_t getBytesPerRow() override; + private: QVulkanInstance instance; - QVulkanWindowRenderer* createRenderer() override; + QVulkanWindowRenderer *createRenderer() override; friend class VulkanRendererEmu; friend class VulkanRenderer2; - VulkanRenderer2* renderer; + VulkanRenderer2 *renderer; }; #endif diff --git a/src/qt/qt_winmanagerfilter.cpp b/src/qt/qt_winmanagerfilter.cpp index 2c6053839..d9a6208b1 100644 --- a/src/qt/qt_winmanagerfilter.cpp +++ b/src/qt/qt_winmanagerfilter.cpp @@ -19,14 +19,13 @@ #include #include <86box/win.h> -bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +bool +WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { - if (eventType == "windows_generic_MSG") - { + if (eventType == "windows_generic_MSG") { MSG *msg = static_cast(message); - switch (msg->message) - { + switch (msg->message) { case WM_SHOWSETTINGS: emit showsettings(); return true; @@ -51,14 +50,12 @@ bool WindowsManagerFilter::nativeEventFilter(const QByteArray &eventType, void * return false; } -bool WindowsManagerFilter::eventFilter(QObject *obj, QEvent *event) +bool +WindowsManagerFilter::eventFilter(QObject *obj, QEvent *event) { - if (event->type() == QEvent::WindowBlocked) - { + if (event->type() == QEvent::WindowBlocked) { emit dialogstatus(1); - } - else if (event->type() == QEvent::WindowUnblocked) - { + } else if (event->type() == QEvent::WindowUnblocked) { emit dialogstatus(0); } diff --git a/src/qt/qt_winmanagerfilter.hpp b/src/qt/qt_winmanagerfilter.hpp index d715d9322..cd141e93f 100644 --- a/src/qt/qt_winmanagerfilter.hpp +++ b/src/qt/qt_winmanagerfilter.hpp @@ -23,17 +23,16 @@ #include #if QT_VERSION_MAJOR >= 6 -#define result_t qintptr +# define result_t qintptr #else -#define result_t long +# define result_t long #endif /* * Filters native events for messages from VM-manager and * window blocked events to notify about open modal dialogs. */ -class WindowsManagerFilter : public QObject, public QAbstractNativeEventFilter -{ +class WindowsManagerFilter : public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: diff --git a/src/qt/qt_winrawinputfilter.cpp b/src/qt/qt_winrawinputfilter.cpp index e798093c0..56d8c9ec9 100644 --- a/src/qt/qt_winrawinputfilter.cpp +++ b/src/qt/qt_winrawinputfilter.cpp @@ -45,24 +45,20 @@ #include extern "C" void win_joystick_handle(PRAWINPUT); -std::unique_ptr WindowsRawInputFilter::Register(QMainWindow *window) +std::unique_ptr +WindowsRawInputFilter::Register(QMainWindow *window) { - HWND wnd = (HWND)window->winId(); + HWND wnd = (HWND) window->winId(); - RAWINPUTDEVICE rid[2] = - { - { - .usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_NOHOTKEYS, - .hwndTarget = wnd - }, - { - .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = 0, - .hwndTarget = wnd - } + RAWINPUTDEVICE rid[2] = { + {.usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_NOHOTKEYS, + .hwndTarget = wnd}, + { .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = 0, + .hwndTarget = wnd} }; if (RegisterRawInputDevices(rid, 2, sizeof(rid[0])) == FALSE) @@ -77,8 +73,7 @@ WindowsRawInputFilter::WindowsRawInputFilter(QMainWindow *window) { this->window = window; - for (auto menu : window->findChildren()) - { + for (auto menu : window->findChildren()) { connect(menu, &QMenu::aboutToShow, this, [=]() { menus_open++; }); connect(menu, &QMenu::aboutToHide, this, [=]() { menus_open--; }); } @@ -91,29 +86,24 @@ WindowsRawInputFilter::WindowsRawInputFilter(QMainWindow *window) WindowsRawInputFilter::~WindowsRawInputFilter() { - RAWINPUTDEVICE rid[2] = - { - { - .usUsagePage = 0x01, - .usUsage = 0x06, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL - }, - { - .usUsagePage = 0x01, - .usUsage = 0x02, - .dwFlags = RIDEV_REMOVE, - .hwndTarget = NULL - } + RAWINPUTDEVICE rid[2] = { + {.usUsagePage = 0x01, + .usUsage = 0x06, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL}, + { .usUsagePage = 0x01, + .usUsage = 0x02, + .dwFlags = RIDEV_REMOVE, + .hwndTarget = NULL} }; RegisterRawInputDevices(rid, 2, sizeof(rid[0])); } -bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) +bool +WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void *message, result_t *result) { - if (eventType == "windows_generic_MSG") - { + if (eventType == "windows_generic_MSG") { MSG *msg = static_cast(message); if (msg->message == WM_INPUT) { @@ -134,7 +124,8 @@ bool WindowsRawInputFilter::nativeEventFilter(const QByteArray &eventType, void return false; } -void WindowsRawInputFilter::handle_input(HRAWINPUT input) +void +WindowsRawInputFilter::handle_input(HRAWINPUT input) { UINT size = 0; @@ -142,12 +133,10 @@ void WindowsRawInputFilter::handle_input(HRAWINPUT input) std::vector buf(size); - if (GetRawInputData(input, RID_INPUT, buf.data(), &size, sizeof(RAWINPUTHEADER)) == size) - { - PRAWINPUT raw = (PRAWINPUT)buf.data(); + if (GetRawInputData(input, RID_INPUT, buf.data(), &size, sizeof(RAWINPUTHEADER)) == size) { + PRAWINPUT raw = (PRAWINPUT) buf.data(); - switch(raw->header.dwType) - { + switch (raw->header.dwType) { case RIM_TYPEKEYBOARD: keyboard_handle(raw); break; @@ -156,30 +145,30 @@ void WindowsRawInputFilter::handle_input(HRAWINPUT input) mouse_handle(raw); break; case RIM_TYPEHID: - { - win_joystick_handle(raw); - break; - } + { + win_joystick_handle(raw); + break; + } } } } /* The following is more or less a direct copy of the old WIN32 implementation */ -void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) +void +WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) { - USHORT scancode; + USHORT scancode; static int recv_lalt = 0, recv_ralt = 0, recv_tab = 0; RAWKEYBOARD rawKB = raw->data.keyboard; - scancode = rawKB.MakeCode; + scancode = rawKB.MakeCode; if (kbd_req_capture && !mouse_capture) return; /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) - { + if (!(rawKB.Flags & RI_KEY_E1)) { if (rawKB.Flags & RI_KEY_E0) scancode |= 0x100; @@ -196,15 +185,10 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) We use scan code 0xFFFF to mean a mapping that has a prefix other than E0 and that is not E1 1D, which is, for our purposes, invalid. */ - if ((scancode == 0x00F) && - !(rawKB.Flags & RI_KEY_BREAK) && - (recv_lalt || recv_ralt) && - !mouse_capture) - { + if ((scancode == 0x00F) && !(rawKB.Flags & RI_KEY_BREAK) && (recv_lalt || recv_ralt) && !mouse_capture) { /* We received a TAB while ALT was pressed, while the mouse is not captured, suppress the TAB and send an ALT key up. */ - if (recv_lalt) - { + if (recv_lalt) { keyboard_input(0, 0x038); /* Extra key press and release so the guest is not stuck in the menu bar. */ @@ -212,8 +196,7 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) keyboard_input(0, 0x038); recv_lalt = 0; } - if (recv_ralt) - { + if (recv_ralt) { keyboard_input(0, 0x138); /* Extra key press and release so the guest is not stuck in the menu bar. */ @@ -221,30 +204,22 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) keyboard_input(0, 0x138); recv_ralt = 0; } - } - else if (((scancode == 0x038) || (scancode == 0x138)) && - !(rawKB.Flags & RI_KEY_BREAK) && - recv_tab && - !mouse_capture) - { + } else if (((scancode == 0x038) || (scancode == 0x138)) && !(rawKB.Flags & RI_KEY_BREAK) && recv_tab && !mouse_capture) { /* We received an ALT while TAB was pressed, while the mouse is not captured, suppress the ALT and send a TAB key up. */ keyboard_input(0, 0x00F); recv_tab = 0; - } - else - { - switch (scancode) - { - case 0x00F: - recv_tab = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x038: - recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); - break; - case 0x138: - recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); - break; + } else { + switch (scancode) { + case 0x00F: + recv_tab = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x038: + recv_lalt = !(rawKB.Flags & RI_KEY_BREAK); + break; + case 0x138: + recv_ralt = !(rawKB.Flags & RI_KEY_BREAK); + break; } /* Translate right CTRL to left ALT if the user has so @@ -257,18 +232,14 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); } - } - else - { - if (rawKB.MakeCode == 0x1D) - { + } else { + if (rawKB.MakeCode == 0x1D) { scancode = scancode_map[0x100]; /* Translate E1 1D to 0x100 (which would otherwise be E0 00 but that is invalid anyway). Also, take a potential mapping into account. */ - } - else + } else scancode = 0xFFFF; if (scancode != 0xFFFF) keyboard_input(!(rawKB.Flags & RI_KEY_BREAK), scancode); @@ -277,7 +248,8 @@ void WindowsRawInputFilter::keyboard_handle(PRAWINPUT raw) /* This is so we can disambiguate scan codes that would otherwise conflict and get passed on incorrectly. */ -UINT16 WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) +UINT16 +WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) { if ((scan_code & 0xff00) == 0xe000) scan_code = (scan_code & 0xff) | 0x0100; @@ -293,19 +265,20 @@ UINT16 WindowsRawInputFilter::convert_scan_code(UINT16 scan_code) return scan_code; } -void WindowsRawInputFilter::keyboard_getkeymap() +void +WindowsRawInputFilter::keyboard_getkeymap() { - const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - const LPCSTR valueName = "Scancode Map"; + const LPCSTR keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + const LPCSTR valueName = "Scancode Map"; unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - UINT32 *bufEx2; - int scMapCount; - UINT16 *bufEx; - int scancode_unmapped; - int scancode_mapped; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; /* First, prepare the default scan code map list which is 1:1. * Remappings will be inserted directly into it. @@ -318,24 +291,20 @@ void WindowsRawInputFilter::keyboard_getkeymap() /* Get the scan code remappings from: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ bufSize = 32768; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) - { - if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) - { - bufEx2 = (UINT32 *)buf; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) { + if (RegQueryValueExA(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) { + bufEx2 = (UINT32 *) buf; scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) - { - bufEx = (UINT16 *)(buf + 12); - for (j = 0; j < scMapCount * 2; j += 2) - { + if ((bufSize != 0) && (scMapCount != 0)) { + bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount * 2; j += 2) { /* Each scan code is 32-bit: 16 bits of remapped scan code, and 16 bits of original scan code. */ scancode_unmapped = bufEx[j + 1]; - scancode_mapped = bufEx[j]; + scancode_mapped = bufEx[j]; scancode_unmapped = convert_scan_code(scancode_unmapped); - scancode_mapped = convert_scan_code(scancode_mapped); + scancode_mapped = convert_scan_code(scancode_mapped); /* Ignore source scan codes with prefixes other than E1 that are not E1 1D. */ @@ -348,9 +317,10 @@ void WindowsRawInputFilter::keyboard_getkeymap() } } -void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) +void +WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) { - RAWMOUSE state = raw->data.mouse; + RAWMOUSE state = raw->data.mouse; static int x, y; /* read mouse buttons and wheel */ @@ -369,13 +339,11 @@ void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) else if (state.usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) buttons &= ~2; - if (state.usButtonFlags & RI_MOUSE_WHEEL) - { - dwheel += (SHORT)state.usButtonData / 120; + if (state.usButtonFlags & RI_MOUSE_WHEEL) { + dwheel += (SHORT) state.usButtonData / 120; } - if (state.usFlags & MOUSE_MOVE_ABSOLUTE) - { + if (state.usFlags & MOUSE_MOVE_ABSOLUTE) { /* absolute mouse, i.e. RDP or VNC * seems to work fine for RDP on Windows 10 * Not sure about other environments. @@ -384,46 +352,42 @@ void WindowsRawInputFilter::mouse_handle(PRAWINPUT raw) dy += (state.lLastY - y) / 25; x = state.lLastX; y = state.lLastY; - } - else - { + } else { /* relative mouse, i.e. regular mouse */ dx += state.lLastX; dy += state.lLastY; } - HWND wnd = (HWND)window->winId(); + HWND wnd = (HWND) window->winId(); RECT rect; GetWindowRect(wnd, &rect); int left = rect.left + (rect.right - rect.left) / 2; - int top = rect.top + (rect.bottom - rect.top) / 2; + int top = rect.top + (rect.bottom - rect.top) / 2; SetCursorPos(left, top); } -void WindowsRawInputFilter::mousePoll() +void +WindowsRawInputFilter::mousePoll() { - if (mouse_capture || video_fullscreen) - { + if (mouse_capture || video_fullscreen) { static int b = 0; - if (dx != 0 || dy != 0 || dwheel != 0) - { + if (dx != 0 || dy != 0 || dwheel != 0) { mouse_x += dx; mouse_y += dy; mouse_z = dwheel; - dx = 0; - dy = 0; + dx = 0; + dy = 0; dwheel = 0; } - if (b != buttons) - { + if (b != buttons) { mouse_buttons = buttons; - b = buttons; + b = buttons; } } } diff --git a/src/qt/qt_winrawinputfilter.hpp b/src/qt/qt_winrawinputfilter.hpp index dabd3f4dd..252f7206c 100644 --- a/src/qt/qt_winrawinputfilter.hpp +++ b/src/qt/qt_winrawinputfilter.hpp @@ -41,13 +41,12 @@ #include #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) -#define result_t qintptr +# define result_t qintptr #else -#define result_t long +# define result_t long #endif -class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter -{ +class WindowsRawInputFilter : public QObject, public QAbstractNativeEventFilter { Q_OBJECT public: @@ -62,20 +61,20 @@ public slots: private: QMainWindow *window; - uint16_t scancode_map[768]; - int buttons = 0; - int dx = 0; - int dy = 0; - int dwheel = 0; - int menus_open = 0; + uint16_t scancode_map[768]; + int buttons = 0; + int dx = 0; + int dy = 0; + int dwheel = 0; + int menus_open = 0; WindowsRawInputFilter(QMainWindow *window); - void handle_input(HRAWINPUT input); - void keyboard_handle(PRAWINPUT raw); - void mouse_handle(PRAWINPUT raw); + void handle_input(HRAWINPUT input); + void keyboard_handle(PRAWINPUT raw); + void mouse_handle(PRAWINPUT raw); static UINT16 convert_scan_code(UINT16 scan_code); - void keyboard_getkeymap(); + void keyboard_getkeymap(); }; #endif diff --git a/src/qt/sdl_joystick.cpp b/src/qt/sdl_joystick.cpp index ab72145c3..06f0a73b8 100644 --- a/src/qt/sdl_joystick.cpp +++ b/src/qt/sdl_joystick.cpp @@ -8,50 +8,47 @@ extern "C" { #include <86box/device.h> #include <86box/gameport.h> -int joysticks_present; -joystick_t joystick_state[MAX_JOYSTICKS]; -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +int joysticks_present; +joystick_t joystick_state[MAX_JOYSTICKS]; +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS]; } #include #ifndef M_PI -#define M_PI 3.14159265358979323846 +# define M_PI 3.14159265358979323846 #endif -void joystick_init() { +void +joystick_init() +{ if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) { return; } joysticks_present = SDL_NumJoysticks(); memset(sdl_joy, 0, sizeof(sdl_joy)); - for (int c = 0; c < joysticks_present; c++) - { + for (int c = 0; c < joysticks_present; c++) { sdl_joy[c] = SDL_JoystickOpen(c); - if (sdl_joy[c]) - { + if (sdl_joy[c]) { int d; strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64); - plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); + plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]); plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]); - plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); + plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]); - for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) - { + for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) { sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d); plat_joystick_state[c].axis[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) - { + for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) { sprintf(plat_joystick_state[c].button[d].name, "Button %i", d); plat_joystick_state[c].button[d].id = d; } - for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) - { + for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) { sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d); plat_joystick_state[c].pov[d].id = d; } @@ -59,59 +56,63 @@ void joystick_init() { } } -void joystick_close() +void +joystick_close() { int c; - for (c = 0; c < joysticks_present; c++) - { + for (c = 0; c < joysticks_present; c++) { if (sdl_joy[c]) SDL_JoystickClose(sdl_joy[c]); } } -static int joystick_get_axis(int joystick_nr, int mapping) +static int +joystick_get_axis(int joystick_nr, int mapping) { - if (mapping & POV_X) - { - switch (plat_joystick_state[joystick_nr].p[mapping & 3]) - { - case SDL_HAT_LEFTUP: case SDL_HAT_LEFT: case SDL_HAT_LEFTDOWN: - return -32767; + if (mapping & POV_X) { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { + case SDL_HAT_LEFTUP: + case SDL_HAT_LEFT: + case SDL_HAT_LEFTDOWN: + return -32767; - case SDL_HAT_RIGHTUP: case SDL_HAT_RIGHT: case SDL_HAT_RIGHTDOWN: - return 32767; + case SDL_HAT_RIGHTUP: + case SDL_HAT_RIGHT: + case SDL_HAT_RIGHTDOWN: + return 32767; - default: - return 0; + default: + return 0; } - } - else if (mapping & POV_Y) - { - switch (plat_joystick_state[joystick_nr].p[mapping & 3]) - { - case SDL_HAT_LEFTUP: case SDL_HAT_UP: case SDL_HAT_RIGHTUP: - return -32767; + } else if (mapping & POV_Y) { + switch (plat_joystick_state[joystick_nr].p[mapping & 3]) { + case SDL_HAT_LEFTUP: + case SDL_HAT_UP: + case SDL_HAT_RIGHTUP: + return -32767; - case SDL_HAT_LEFTDOWN: case SDL_HAT_DOWN: case SDL_HAT_RIGHTDOWN: - return 32767; + case SDL_HAT_LEFTDOWN: + case SDL_HAT_DOWN: + case SDL_HAT_RIGHTDOWN: + return 32767; - default: - return 0; + default: + return 0; } - } - else + } else return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; } -void joystick_process() +void +joystick_process() { int c, d; - if (!joystick_type) return; + if (!joystick_type) + return; SDL_JoystickUpdate(); - for (c = 0; c < joysticks_present; c++) - { + for (c = 0; c < joysticks_present; c++) { int b; plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0); @@ -129,35 +130,30 @@ void joystick_process() // pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (joystick_state[c].plat_joystick_nr) - { + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + if (joystick_state[c].plat_joystick_nr) { int joystick_nr = joystick_state[c].plat_joystick_nr - 1; for (d = 0; d < joystick_get_axis_count(joystick_type); d++) joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); for (d = 0; d < joystick_get_button_count(joystick_type); d++) joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - int x, y; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + int x, y; double angle, magnitude; x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); - magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); + magnitude = sqrt((double) x * (double) x + (double) y * (double) y); if (magnitude < 16384) joystick_state[c].pov[d] = -1; else - joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; } - } - else - { + } else { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) joystick_state[c].axis[d] = 0; for (d = 0; d < joystick_get_button_count(joystick_type); d++) diff --git a/src/qt/win_dynld.c b/src/qt/win_dynld.c index 98eb4739f..66fd0503d 100644 --- a/src/qt/win_dynld.c +++ b/src/qt/win_dynld.c @@ -25,63 +25,59 @@ #include <86box/86box.h> #include <86box/plat_dynld.h> - #ifdef ENABLE_DYNLD_LOG int dynld_do_log = ENABLE_DYNLD_LOG; - static void dynld_log(const char *fmt, ...) { va_list ap; if (dynld_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define dynld_log(fmt, ...) +# define dynld_log(fmt, ...) #endif - void * dynld_module(const char *name, dllimp_t *table) { - HMODULE h; + HMODULE h; dllimp_t *imp; - void *func; + void *func; /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { - dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return(NULL); + dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); + return (NULL); } /* Now load the desired function pointers. */ - for (imp=table; imp->name!=NULL; imp++) { - func = GetProcAddress(h, imp->name); - if (func == NULL) { - dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", - name, imp->name, GetLastError()); - FreeLibrary(h); - return(NULL); - } + for (imp = table; imp->name != NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", + name, imp->name, GetLastError()); + FreeLibrary(h); + return (NULL); + } - /* To overcome typing issues.. */ - *(char **)imp->func = (char *)func; + /* To overcome typing issues.. */ + *(char **) imp->func = (char *) func; } /* All good. */ dynld_log("loaded %s\n", name); - return((void *)h); + return ((void *) h); } - void dynld_close(void *handle) { if (handle != NULL) - FreeLibrary((HMODULE)handle); + FreeLibrary((HMODULE) handle); } diff --git a/src/qt/win_joystick_rawinput.c b/src/qt/win_joystick_rawinput.c index db0476513..f41131b28 100644 --- a/src/qt/win_joystick_rawinput.c +++ b/src/qt/win_joystick_rawinput.c @@ -39,431 +39,444 @@ int joystick_do_log = ENABLE_JOYSTICK_LOG; static void joystick_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (joystick_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); - } + if (joystick_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } } #else -#define joystick_log(fmt, ...) +# define joystick_log(fmt, ...) #endif typedef struct { - HANDLE hdevice; - PHIDP_PREPARSED_DATA data; + HANDLE hdevice; + PHIDP_PREPARSED_DATA data; - USAGE usage_button[256]; + USAGE usage_button[256]; - struct raw_axis_t { - USAGE usage; - USHORT link; - USHORT bitsize; - LONG max; - LONG min; - } axis[8]; + struct raw_axis_t { + USAGE usage; + USHORT link; + USHORT bitsize; + LONG max; + LONG min; + } axis[8]; - struct raw_pov_t { - USAGE usage; - USHORT link; - LONG max; - LONG min; - } pov[4]; + struct raw_pov_t { + USAGE usage; + USHORT link; + LONG max; + LONG min; + } pov[4]; } raw_joystick_t; plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; -int joysticks_present = 0; +joystick_t joystick_state[MAX_JOYSTICKS]; +int joysticks_present = 0; raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS]; /* We only use the first 32 buttons reported, from Usage ID 1-128 */ -void joystick_add_button(raw_joystick_t* rawjoy, plat_joystick_t* joy, USAGE usage) { - if (joy->nr_buttons >= 32) return; - if (usage < 1 || usage > 128) return; - - rawjoy->usage_button[usage] = joy->nr_buttons; - sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); - joy->nr_buttons++; -} - -void joystick_add_axis(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_axes >= 8) return; - - switch (prop->Range.UsageMin) { - case HID_USAGE_GENERIC_X: - sprintf(joy->axis[joy->nr_axes].name, "X"); - break; - case HID_USAGE_GENERIC_Y: - sprintf(joy->axis[joy->nr_axes].name, "Y"); - break; - case HID_USAGE_GENERIC_Z: - sprintf(joy->axis[joy->nr_axes].name, "Z"); - break; - case HID_USAGE_GENERIC_RX: - sprintf(joy->axis[joy->nr_axes].name, "RX"); - break; - case HID_USAGE_GENERIC_RY: - sprintf(joy->axis[joy->nr_axes].name, "RY"); - break; - case HID_USAGE_GENERIC_RZ: - sprintf(joy->axis[joy->nr_axes].name, "RZ"); - break; - default: - return; - } - - joy->axis[joy->nr_axes].id = joy->nr_axes; - rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; - rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; - rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; - - /* Assume unsigned when min >= 0 */ - if (prop->LogicalMin < 0) { - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; - } else { - /* - * Some joysticks will send -1 in LogicalMax, like Xbox Controllers - * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) - */ - rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); - } - rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; - - joy->nr_axes++; -} - -void joystick_add_pov(raw_joystick_t* rawjoy, plat_joystick_t* joy, PHIDP_VALUE_CAPS prop) { - if (joy->nr_povs >= 4) return; - - sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs+1); - rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; - rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; - rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; - rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; - - joy->nr_povs++; -} - -void joystick_get_capabilities(raw_joystick_t* rawjoy, plat_joystick_t* joy) { - UINT size = 0; - PHIDP_BUTTON_CAPS btn_caps = NULL; - PHIDP_VALUE_CAPS val_caps = NULL; - - /* Get preparsed data (HID data format) */ - GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); - rawjoy->data = malloc(size); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); - - HIDP_CAPS caps; - HidP_GetCaps(rawjoy->data, &caps); - - /* Buttons */ - if (caps.NumberInputButtonCaps > 0) { - btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); - if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c=0; c 0) { - val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); - if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { - joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); - goto end; - } - /* We only detect generic stuff */ - for (int c=0; chdevice, RIDI_DEVICENAME, device_name, &size); - device_name = calloc(size, sizeof(WCHAR)); - if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) - fatal("joystick_get_capabilities: Failed to get device name.\n"); - - HANDLE hDevObj = CreateFileW(device_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (hDevObj) { - HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); - CloseHandle(hDevObj); - } - free(device_name); - - int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); - if (result == 0 || strlen(joy->name) == 0) - sprintf(joy->name, - "RawInput %s, VID:%04lX PID:%04lX", - info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", - info->hid.dwVendorId, - info->hid.dwProductId); -} - -void joystick_init(void) +void +joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage) { - UINT size = 0; - atexit(joystick_close); + if (joy->nr_buttons >= 32) + return; + if (usage < 1 || usage > 128) + return; - joysticks_present = 0; - memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); - - /* Get a list of raw input devices from Windows */ - UINT raw_devices = 0; - GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); - GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); - - for (int i=0; i= MAX_PLAT_JOYSTICKS) break; - if (deviceList[i].dwType != RIM_TYPEHID) continue; - - /* Get device info: hardware IDs and usage IDs */ - GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); - info = malloc(size); - info->cbSize = sizeof(RID_DEVICE_INFO); - if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) - goto end_loop; - - /* If this is not a joystick/gamepad, skip */ - if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) goto end_loop; - if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && - info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) goto end_loop; - - plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; - raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; - rawjoy->hdevice = deviceList[i].hDevice; - - joystick_get_capabilities(rawjoy, joy); - joystick_get_device_name(rawjoy, joy, info); - - joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", - joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); - - joysticks_present++; - - end_loop: - free(info); - } - - joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); - - /* Initialize the RawInput (joystick and gamepad) module. */ - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = 0; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; - - ridev[1].dwFlags = 0; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; - - if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) - fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); + rawjoy->usage_button[usage] = joy->nr_buttons; + sprintf(joy->button[joy->nr_buttons].name, "Button %d", usage); + joy->nr_buttons++; } -void joystick_close(void) +void +joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - RAWINPUTDEVICE ridev[2]; - ridev[0].dwFlags = RIDEV_REMOVE; - ridev[0].hwndTarget = NULL; - ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + if (joy->nr_axes >= 8) + return; - ridev[1].dwFlags = RIDEV_REMOVE; - ridev[1].hwndTarget = NULL; - ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; - ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + switch (prop->Range.UsageMin) { + case HID_USAGE_GENERIC_X: + sprintf(joy->axis[joy->nr_axes].name, "X"); + break; + case HID_USAGE_GENERIC_Y: + sprintf(joy->axis[joy->nr_axes].name, "Y"); + break; + case HID_USAGE_GENERIC_Z: + sprintf(joy->axis[joy->nr_axes].name, "Z"); + break; + case HID_USAGE_GENERIC_RX: + sprintf(joy->axis[joy->nr_axes].name, "RX"); + break; + case HID_USAGE_GENERIC_RY: + sprintf(joy->axis[joy->nr_axes].name, "RY"); + break; + case HID_USAGE_GENERIC_RZ: + sprintf(joy->axis[joy->nr_axes].name, "RZ"); + break; + default: + return; + } - RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); + joy->axis[joy->nr_axes].id = joy->nr_axes; + rawjoy->axis[joy->nr_axes].usage = prop->Range.UsageMin; + rawjoy->axis[joy->nr_axes].link = prop->LinkCollection; + rawjoy->axis[joy->nr_axes].bitsize = prop->BitSize; + + /* Assume unsigned when min >= 0 */ + if (prop->LogicalMin < 0) { + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax; + } else { + /* + * Some joysticks will send -1 in LogicalMax, like Xbox Controllers + * so we need to mask that to appropriate value (instead of 0xFFFFFFFF) + */ + rawjoy->axis[joy->nr_axes].max = prop->LogicalMax & ((1 << prop->BitSize) - 1); + } + rawjoy->axis[joy->nr_axes].min = prop->LogicalMin; + + joy->nr_axes++; } - -void win_joystick_handle(PRAWINPUT raw) +void +joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop) { - HRESULT r; - int j = -1; /* current joystick index, -1 when not found */ + if (joy->nr_povs >= 4) + return; - /* If the input is not from a known device, we ignore it */ - for (int i=0; iheader.hDevice) { - j = i; - break; - } - } - if (j == -1) return; + sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1); + rawjoy->pov[joy->nr_povs].usage = prop->Range.UsageMin; + rawjoy->pov[joy->nr_povs].link = prop->LinkCollection; + rawjoy->pov[joy->nr_povs].min = prop->LogicalMin; + rawjoy->pov[joy->nr_povs].max = prop->LogicalMax; - /* Read buttons */ - USAGE usage_list[128] = {0}; - ULONG usage_length = plat_joystick_state[j].nr_buttons; - memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); - - r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, - raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - for (int i=0; imax - axis->min + 1) / 2; - - r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS) { - if (axis->min < 0) { - /* extend signed uvalue to LONG */ - if (uvalue & (1 << (axis->bitsize-1))) { - ULONG mask = (1 << axis->bitsize) - 1; - value = -1U ^ mask; - value |= uvalue; - } else { - value = uvalue; - } - } else { - /* Assume unsigned when min >= 0, convert to a signed value */ - value = (LONG)uvalue - center; - } - if (abs(value) == 1) value = 0; - value = value * 32768 / center; - } - - plat_joystick_state[j].a[a] = value; - //joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); - } - - /* read povs */ - for (int p=0; plink, pov->usage, &uvalue, - raw_joystick_state[j].data, (PCHAR)raw->data.hid.bRawData, raw->data.hid.dwSizeHid); - - if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { - value = (uvalue - pov->min) * 36000; - value /= (pov->max - pov->min + 1); - value %= 36000; - } - - plat_joystick_state[j].p[p] = value; - - //joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); - - } - //joystick_log("\n"); + joy->nr_povs++; } - -static int joystick_get_axis(int joystick_nr, int mapping) +void +joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy) { - if (mapping & POV_X) - { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2*M_PI * (double)pov) / 36000.0) * 32767; - } - else if (mapping & POV_Y) - { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + UINT size = 0; + PHIDP_BUTTON_CAPS btn_caps = NULL; + PHIDP_VALUE_CAPS val_caps = NULL; - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; - } - else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; + /* Get preparsed data (HID data format) */ + GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size); + rawjoy->data = malloc(size); + if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0) + fatal("joystick_get_capabilities: Failed to get preparsed data.\n"); + HIDP_CAPS caps; + HidP_GetCaps(rawjoy->data, &caps); + + /* Buttons */ + if (caps.NumberInputButtonCaps > 0) { + btn_caps = calloc(caps.NumberInputButtonCaps, sizeof(HIDP_BUTTON_CAPS)); + if (HidP_GetButtonCaps(HidP_Input, btn_caps, &caps.NumberInputButtonCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { + joystick_log("joystick_get_capabilities: Failed to query input buttons.\n"); + goto end; + } + /* We only detect generic stuff */ + for (int c = 0; c < caps.NumberInputButtonCaps; c++) { + if (btn_caps[c].UsagePage != HID_USAGE_PAGE_BUTTON) + continue; + + int button_count = btn_caps[c].Range.UsageMax - btn_caps[c].Range.UsageMin + 1; + for (int b = 0; b < button_count; b++) { + joystick_add_button(rawjoy, joy, b + btn_caps[c].Range.UsageMin); + } + } + } + + /* Values (axes and povs) */ + if (caps.NumberInputValueCaps > 0) { + val_caps = calloc(caps.NumberInputValueCaps, sizeof(HIDP_VALUE_CAPS)); + if (HidP_GetValueCaps(HidP_Input, val_caps, &caps.NumberInputValueCaps, rawjoy->data) != HIDP_STATUS_SUCCESS) { + joystick_log("joystick_get_capabilities: Failed to query axes and povs.\n"); + goto end; + } + /* We only detect generic stuff */ + for (int c = 0; c < caps.NumberInputValueCaps; c++) { + if (val_caps[c].UsagePage != HID_USAGE_PAGE_GENERIC) + continue; + + if (val_caps[c].Range.UsageMin == HID_USAGE_GENERIC_HATSWITCH) + joystick_add_pov(rawjoy, joy, &val_caps[c]); + else + joystick_add_axis(rawjoy, joy, &val_caps[c]); + } + } + +end: + free(btn_caps); + free(val_caps); } - -void joystick_process(void) +void +joystick_get_device_name(raw_joystick_t *rawjoy, plat_joystick_t *joy, PRID_DEVICE_INFO info) { - int c, d; + UINT size = 0; + WCHAR *device_name = NULL; + WCHAR device_desc_wide[200] = { 0 }; - if (joystick_type == 7) return; + GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size); + device_name = calloc(size, sizeof(WCHAR)); + if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_DEVICENAME, device_name, &size) <= 0) + fatal("joystick_get_capabilities: Failed to get device name.\n"); - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (joystick_state[c].plat_joystick_nr) - { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + HANDLE hDevObj = CreateFileW(device_name, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hDevObj) { + HidD_GetProductString(hDevObj, device_desc_wide, sizeof(WCHAR) * 200); + CloseHandle(hDevObj); + } + free(device_name); - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - int x, y; - double angle, magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); - magnitude = sqrt((double)x*(double)x + (double)y*(double)y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; - } - } - else - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } + int result = WideCharToMultiByte(CP_ACP, 0, device_desc_wide, 200, joy->name, 260, NULL, NULL); + if (result == 0 || strlen(joy->name) == 0) + sprintf(joy->name, + "RawInput %s, VID:%04lX PID:%04lX", + info->hid.usUsage == HID_USAGE_GENERIC_JOYSTICK ? "Joystick" : "Gamepad", + info->hid.dwVendorId, + info->hid.dwProductId); +} + +void +joystick_init(void) +{ + UINT size = 0; + atexit(joystick_close); + + joysticks_present = 0; + memset(raw_joystick_state, 0, sizeof(raw_joystick_t) * MAX_PLAT_JOYSTICKS); + + /* Get a list of raw input devices from Windows */ + UINT raw_devices = 0; + GetRawInputDeviceList(NULL, &raw_devices, sizeof(RAWINPUTDEVICELIST)); + PRAWINPUTDEVICELIST deviceList = calloc(raw_devices, sizeof(RAWINPUTDEVICELIST)); + GetRawInputDeviceList(deviceList, &raw_devices, sizeof(RAWINPUTDEVICELIST)); + + for (int i = 0; i < raw_devices; i++) { + PRID_DEVICE_INFO info = NULL; + + if (joysticks_present >= MAX_PLAT_JOYSTICKS) + break; + if (deviceList[i].dwType != RIM_TYPEHID) + continue; + + /* Get device info: hardware IDs and usage IDs */ + GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, NULL, &size); + info = malloc(size); + info->cbSize = sizeof(RID_DEVICE_INFO); + if (GetRawInputDeviceInfoA(deviceList[i].hDevice, RIDI_DEVICEINFO, info, &size) <= 0) + goto end_loop; + + /* If this is not a joystick/gamepad, skip */ + if (info->hid.usUsagePage != HID_USAGE_PAGE_GENERIC) + goto end_loop; + if (info->hid.usUsage != HID_USAGE_GENERIC_JOYSTICK && info->hid.usUsage != HID_USAGE_GENERIC_GAMEPAD) + goto end_loop; + + plat_joystick_t *joy = &plat_joystick_state[joysticks_present]; + raw_joystick_t *rawjoy = &raw_joystick_state[joysticks_present]; + rawjoy->hdevice = deviceList[i].hDevice; + + joystick_get_capabilities(rawjoy, joy); + joystick_get_device_name(rawjoy, joy, info); + + joystick_log("joystick_init: %s - %d buttons, %d axes, %d POVs\n", + joy->name, joy->nr_buttons, joy->nr_axes, joy->nr_povs); + + joysticks_present++; + +end_loop: + free(info); + } + + joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present); + + /* Initialize the RawInput (joystick and gamepad) module. */ + RAWINPUTDEVICE ridev[2]; + ridev[0].dwFlags = 0; + ridev[0].hwndTarget = NULL; + ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + + ridev[1].dwFlags = 0; + ridev[1].hwndTarget = NULL; + ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + + if (!RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE))) + fatal("plat_joystick_init: RegisterRawInputDevices failed\n"); +} + +void +joystick_close(void) +{ + RAWINPUTDEVICE ridev[2]; + ridev[0].dwFlags = RIDEV_REMOVE; + ridev[0].hwndTarget = NULL; + ridev[0].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[0].usUsage = HID_USAGE_GENERIC_JOYSTICK; + + ridev[1].dwFlags = RIDEV_REMOVE; + ridev[1].hwndTarget = NULL; + ridev[1].usUsagePage = HID_USAGE_PAGE_GENERIC; + ridev[1].usUsage = HID_USAGE_GENERIC_GAMEPAD; + + RegisterRawInputDevices(ridev, 2, sizeof(RAWINPUTDEVICE)); +} + +void +win_joystick_handle(PRAWINPUT raw) +{ + HRESULT r; + int j = -1; /* current joystick index, -1 when not found */ + + /* If the input is not from a known device, we ignore it */ + for (int i = 0; i < joysticks_present; i++) { + if (raw_joystick_state[i].hdevice == raw->header.hDevice) { + j = i; + break; + } + } + if (j == -1) + return; + + /* Read buttons */ + USAGE usage_list[128] = { 0 }; + ULONG usage_length = plat_joystick_state[j].nr_buttons; + memset(plat_joystick_state[j].b, 0, 32 * sizeof(int)); + + r = HidP_GetUsages(HidP_Input, HID_USAGE_PAGE_BUTTON, 0, usage_list, &usage_length, + raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS) { + for (int i = 0; i < usage_length; i++) { + int button = raw_joystick_state[j].usage_button[usage_list[i]]; + plat_joystick_state[j].b[button] = 128; + } + } + + /* Read axes */ + for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) { + struct raw_axis_t *axis = &raw_joystick_state[j].axis[a]; + ULONG uvalue = 0; + LONG value = 0; + LONG center = (axis->max - axis->min + 1) / 2; + + r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue, + raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS) { + if (axis->min < 0) { + /* extend signed uvalue to LONG */ + if (uvalue & (1 << (axis->bitsize - 1))) { + ULONG mask = (1 << axis->bitsize) - 1; + value = -1U ^ mask; + value |= uvalue; + } else { + value = uvalue; + } + } else { + /* Assume unsigned when min >= 0, convert to a signed value */ + value = (LONG) uvalue - center; + } + if (abs(value) == 1) + value = 0; + value = value * 32768 / center; + } + + plat_joystick_state[j].a[a] = value; + // joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]); + } + + /* read povs */ + for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) { + struct raw_pov_t *pov = &raw_joystick_state[j].pov[p]; + ULONG uvalue = 0; + LONG value = -1; + + r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue, + raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid); + + if (r == HIDP_STATUS_SUCCESS && (uvalue >= pov->min && uvalue <= pov->max)) { + value = (uvalue - pov->min) * 36000; + value /= (pov->max - pov->min + 1); + value %= 36000; + } + + plat_joystick_state[j].p[p] = value; + + // joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]); + } + // joystick_log("\n"); +} + +static int +joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return sin((2 * M_PI * (double) pov) / 36000.0) * 32767; + } else if (mapping & POV_Y) { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return -cos((2 * M_PI * (double) pov) / 36000.0) * 32767; + } else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; +} + +void +joystick_process(void) +{ + int c, d; + + if (joystick_type == 7) + return; + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { + if (joystick_state[c].plat_joystick_nr) { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI); + magnitude = sqrt((double) x * (double) x + (double) y * (double) y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360; + } + } else { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } } diff --git a/src/qt/wl_mouse.cpp b/src/qt/wl_mouse.cpp index 9e487cde3..4cc1b3169 100644 --- a/src/qt/wl_mouse.cpp +++ b/src/qt/wl_mouse.cpp @@ -25,40 +25,39 @@ #include #include -extern "C" -{ +extern "C" { #include <86box/plat.h> } -static zwp_relative_pointer_manager_v1* rel_manager = nullptr; -static zwp_relative_pointer_v1* rel_pointer = nullptr; -static zwp_pointer_constraints_v1* conf_pointer_interface = nullptr; -static zwp_locked_pointer_v1* conf_pointer = nullptr; +static zwp_relative_pointer_manager_v1 *rel_manager = nullptr; +static zwp_relative_pointer_v1 *rel_pointer = nullptr; +static zwp_pointer_constraints_v1 *conf_pointer_interface = nullptr; +static zwp_locked_pointer_v1 *conf_pointer = nullptr; -static int rel_mouse_x = 0, rel_mouse_y = 0; +static int rel_mouse_x = 0, rel_mouse_y = 0; static bool wl_init_ok = false; -void rel_mouse_event(void* data, zwp_relative_pointer_v1* zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) +void +rel_mouse_event(void *data, zwp_relative_pointer_v1 *zwp_relative_pointer_v1, uint32_t tstmp, uint32_t tstmpl, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_real, wl_fixed_t dy_real) { rel_mouse_x += wl_fixed_to_int(dx_real); rel_mouse_y += wl_fixed_to_int(dy_real); } -extern "C" -{ - extern int mouse_x, mouse_y; +extern "C" { +extern int mouse_x, mouse_y; } -void wl_mouse_poll() +void +wl_mouse_poll() { - mouse_x = rel_mouse_x; - mouse_y = rel_mouse_y; + mouse_x = rel_mouse_x; + mouse_y = rel_mouse_y; rel_mouse_x = 0; rel_mouse_y = 0; } -static struct zwp_relative_pointer_v1_listener rel_listener = -{ +static struct zwp_relative_pointer_v1_listener rel_listener = { rel_mouse_event }; @@ -66,13 +65,11 @@ static void display_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) { - if (!strcmp(interface, "zwp_relative_pointer_manager_v1")) - { - rel_manager = (zwp_relative_pointer_manager_v1*)wl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, version); + if (!strcmp(interface, "zwp_relative_pointer_manager_v1")) { + rel_manager = (zwp_relative_pointer_manager_v1 *) wl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, version); } - if (!strcmp(interface, "zwp_pointer_constraints_v1")) - { - conf_pointer_interface = (zwp_pointer_constraints_v1*)wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); + if (!strcmp(interface, "zwp_pointer_constraints_v1")) { + conf_pointer_interface = (zwp_pointer_constraints_v1 *) wl_registry_bind(registry, id, &zwp_pointer_constraints_v1_interface, version); } } @@ -82,7 +79,7 @@ display_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name plat_mouse_capture(0); zwp_relative_pointer_manager_v1_destroy(rel_manager); zwp_pointer_constraints_v1_destroy(conf_pointer_interface); - rel_manager = nullptr; + rel_manager = nullptr; conf_pointer_interface = nullptr; } @@ -91,15 +88,14 @@ static const struct wl_registry_listener registry_listener = { display_global_remove }; -void wl_init() +void +wl_init() { if (!wl_init_ok) { - wl_display* display = (wl_display*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); - if (display) - { + wl_display *display = (wl_display *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"); + if (display) { auto registry = wl_display_get_registry(display); - if (registry) - { + if (registry) { wl_registry_add_listener(registry, ®istry_listener, nullptr); wl_display_roundtrip(display); } @@ -108,19 +104,24 @@ void wl_init() } } -void wl_mouse_capture(QWindow *window) +void +wl_mouse_capture(QWindow *window) { if (rel_manager) { - rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); + rel_pointer = zwp_relative_pointer_manager_v1_get_relative_pointer(rel_manager, (wl_pointer *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer")); zwp_relative_pointer_v1_add_listener(rel_pointer, &rel_listener, nullptr); } - if (conf_pointer_interface) conf_pointer = zwp_pointer_constraints_v1_lock_pointer(conf_pointer_interface, (wl_surface*)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_pointer*)QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"), nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); + if (conf_pointer_interface) + conf_pointer = zwp_pointer_constraints_v1_lock_pointer(conf_pointer_interface, (wl_surface *) QGuiApplication::platformNativeInterface()->nativeResourceForWindow("surface", window), (wl_pointer *) QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_pointer"), nullptr, ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT); } -void wl_mouse_uncapture() +void +wl_mouse_uncapture() { - if (conf_pointer) zwp_locked_pointer_v1_destroy(conf_pointer); - if (rel_pointer) zwp_relative_pointer_v1_destroy(rel_pointer); - rel_pointer = nullptr; + if (conf_pointer) + zwp_locked_pointer_v1_destroy(conf_pointer); + if (rel_pointer) + zwp_relative_pointer_v1_destroy(rel_pointer); + rel_pointer = nullptr; conf_pointer = nullptr; } diff --git a/src/qt/wl_mouse.hpp b/src/qt/wl_mouse.hpp index a62d70fee..25d4de66c 100644 --- a/src/qt/wl_mouse.hpp +++ b/src/qt/wl_mouse.hpp @@ -1,5 +1,5 @@ class QWindow; -void wl_mouse_capture(QWindow* window); +void wl_mouse_capture(QWindow *window); void wl_mouse_uncapture(); void wl_mouse_poll(); void wl_init(); diff --git a/src/qt/xinput2_mouse.cpp b/src/qt/xinput2_mouse.cpp index b1887bedc..5017c78d2 100644 --- a/src/qt/xinput2_mouse.cpp +++ b/src/qt/xinput2_mouse.cpp @@ -23,7 +23,7 @@ #include #include "qt_mainwindow.hpp" -extern MainWindow* main_window; +extern MainWindow *main_window; #include #include @@ -31,8 +31,7 @@ extern MainWindow* main_window; #include -extern "C" -{ +extern "C" { #include #include #include @@ -46,27 +45,29 @@ extern "C" int xi2flides[2] = { 0, 0 }; -static Display* disp = nullptr; -static QThread* procThread = nullptr; -static XIEventMask ximask; -static std::atomic exitfromthread = false; +static Display *disp = nullptr; +static QThread *procThread = nullptr; +static XIEventMask ximask; +static std::atomic exitfromthread = false; static std::atomic xi2_mouse_x = 0, xi2_mouse_y = 0, xi2_mouse_abs_x = 0, xi2_mouse_abs_y = 0; -static int xi2opcode = 0; -static double prev_rel_coords[2] = { 0., 0. }; -static Time prev_time = 0; +static int xi2opcode = 0; +static double prev_rel_coords[2] = { 0., 0. }; +static Time prev_time = 0; // From SDL2. -static void parse_valuators(const double *input_values, const unsigned char *mask,int mask_len, - double *output_values,int output_values_len) { - int i = 0,z = 0; +static void +parse_valuators(const double *input_values, const unsigned char *mask, int mask_len, + double *output_values, int output_values_len) +{ + int i = 0, z = 0; int top = mask_len * 8; if (top > 16) top = 16; - memset(output_values,0,output_values_len * sizeof(double)); + memset(output_values, 0, output_values_len * sizeof(double)); for (; i < top && z < output_values_len; i++) { if (XIMaskIsSet(mask, i)) { - const int value = (int) *input_values; + const int value = (int) *input_values; output_values[z] = value; input_values++; } @@ -76,100 +77,102 @@ static void parse_valuators(const double *input_values, const unsigned char *mas static bool exitthread = false; -void xinput2_proc() +void +xinput2_proc() { Window win; win = DefaultRootWindow(disp); ximask.deviceid = XIAllMasterDevices; ximask.mask_len = XIMaskLen(XI_LASTEVENT); - ximask.mask = (unsigned char*)calloc(ximask.mask_len, sizeof(unsigned char)); + ximask.mask = (unsigned char *) calloc(ximask.mask_len, sizeof(unsigned char)); XISetMask(ximask.mask, XI_RawKeyPress); XISetMask(ximask.mask, XI_RawKeyRelease); XISetMask(ximask.mask, XI_RawButtonPress); XISetMask(ximask.mask, XI_RawButtonRelease); XISetMask(ximask.mask, XI_RawMotion); - if (XKeysymToKeycode(disp, XK_Home) == 69) XISetMask(ximask.mask, XI_Motion); + if (XKeysymToKeycode(disp, XK_Home) == 69) + XISetMask(ximask.mask, XI_Motion); XISelectEvents(disp, win, &ximask, 1); XSync(disp, False); - while(true) - { - XEvent ev; - XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; - XNextEvent(disp, (XEvent*)&ev); + while (true) { + XEvent ev; + XGenericEventCookie *cookie = (XGenericEventCookie *) &ev.xcookie; + XNextEvent(disp, (XEvent *) &ev); if (XGetEventData(disp, cookie) && cookie->type == GenericEvent && cookie->extension == xi2opcode) { switch (cookie->evtype) { - case XI_RawMotion: { - const XIRawEvent *rawev = (const XIRawEvent*)cookie->data; - double relative_coords[2] = { 0., 0. }; - parse_valuators(rawev->raw_values,rawev->valuators.mask, - rawev->valuators.mask_len,relative_coords,2); + case XI_RawMotion: + { + const XIRawEvent *rawev = (const XIRawEvent *) cookie->data; + double relative_coords[2] = { 0., 0. }; + parse_valuators(rawev->raw_values, rawev->valuators.mask, + rawev->valuators.mask_len, relative_coords, 2); - if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) { - break; // Ignore duplicated events. - } - xi2_mouse_x = xi2_mouse_x + relative_coords[0]; - xi2_mouse_y = xi2_mouse_y + relative_coords[1]; - prev_rel_coords[0] = relative_coords[0]; - prev_rel_coords[1] = relative_coords[1]; - prev_time = rawev->time; - if (!mouse_capture) break; - XWindowAttributes winattrib{}; - if (XGetWindowAttributes(disp, main_window->winId(), &winattrib)) { - auto globalPoint = main_window->mapToGlobal(QPoint(main_window->width() / 2, main_window->height() / 2)); - XWarpPointer(disp, XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), 0, 0, 0, 0, globalPoint.x(), globalPoint.y()); - XFlush(disp); - } - - } - case XI_Motion: { - if (XKeysymToKeycode(disp, XK_Home) == 69) { - // No chance we will get raw motion events on VNC. - const XIDeviceEvent *motionev = (const XIDeviceEvent*)cookie->data; - if (xi2_mouse_abs_x != 0 || xi2_mouse_abs_y != 0) { - xi2_mouse_x = xi2_mouse_x + (motionev->event_x - xi2_mouse_abs_x); - xi2_mouse_y = xi2_mouse_y + (motionev->event_y - xi2_mouse_abs_y); + if ((rawev->time == prev_time) && (relative_coords[0] == prev_rel_coords[0]) && (relative_coords[1] == prev_rel_coords[1])) { + break; // Ignore duplicated events. + } + xi2_mouse_x = xi2_mouse_x + relative_coords[0]; + xi2_mouse_y = xi2_mouse_y + relative_coords[1]; + prev_rel_coords[0] = relative_coords[0]; + prev_rel_coords[1] = relative_coords[1]; + prev_time = rawev->time; + if (!mouse_capture) + break; + XWindowAttributes winattrib {}; + if (XGetWindowAttributes(disp, main_window->winId(), &winattrib)) { + auto globalPoint = main_window->mapToGlobal(QPoint(main_window->width() / 2, main_window->height() / 2)); + XWarpPointer(disp, XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), XRootWindow(disp, XScreenNumberOfScreen(winattrib.screen)), 0, 0, 0, 0, globalPoint.x(), globalPoint.y()); + XFlush(disp); + } + } + case XI_Motion: + { + if (XKeysymToKeycode(disp, XK_Home) == 69) { + // No chance we will get raw motion events on VNC. + const XIDeviceEvent *motionev = (const XIDeviceEvent *) cookie->data; + if (xi2_mouse_abs_x != 0 || xi2_mouse_abs_y != 0) { + xi2_mouse_x = xi2_mouse_x + (motionev->event_x - xi2_mouse_abs_x); + xi2_mouse_y = xi2_mouse_y + (motionev->event_y - xi2_mouse_abs_y); + } + xi2_mouse_abs_x = motionev->event_x; + xi2_mouse_abs_y = motionev->event_y; } - xi2_mouse_abs_x = motionev->event_x; - xi2_mouse_abs_y = motionev->event_y; } - } } } XFreeEventData(disp, cookie); - if (exitthread) break; + if (exitthread) + break; } XCloseDisplay(disp); } -void xinput2_exit() +void +xinput2_exit() { - if (!exitthread) - { + if (!exitthread) { exitthread = true; procThread->wait(5000); procThread->terminate(); } } -void xinput2_init() +void +xinput2_init() { disp = XOpenDisplay(nullptr); - if (!disp) - { + if (!disp) { qWarning() << "Cannot open current X11 display"; return; } auto event = 0, err = 0, minor = 1, major = 2; - if (XQueryExtension(disp, "XInputExtension", &xi2opcode, &event, &err)) - { - if (XIQueryVersion(disp, &major, &minor) == Success) - { + if (XQueryExtension(disp, "XInputExtension", &xi2opcode, &event, &err)) { + if (XIQueryVersion(disp, &major, &minor) == Success) { procThread = QThread::create(xinput2_proc); procThread->start(); atexit(xinput2_exit); @@ -177,10 +180,10 @@ void xinput2_init() } } -void xinput2_poll() +void +xinput2_poll() { - if (procThread && mouse_capture) - { + if (procThread && mouse_capture) { mouse_x = xi2_mouse_x; mouse_y = xi2_mouse_y; } diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index c7b0995ee..5f9abe8d6 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -179,8 +179,8 @@ scsi_card_init(void) if (machine_has_flags(machine, MACHINE_SCSI)) max--; -/* Do not initialize any controllers if we have do not have any SCSI - bus left. */ + /* Do not initialize any controllers if we have do not have any SCSI + bus left. */ if (max > 0) { for (i = 0; i < max; i++) { if (!scsi_cards[scsi_card_current[i]].device) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 7947c1eed..f6924864d 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -62,98 +62,98 @@ typedef struct /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ const uint8_t scsi_cdrom_command_flags[0x100] = { - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ - IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ - 0, /* 0x02 */ - IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, /* 0x04-0x07 */ - IMPLEMENTED | CHECK_READY, /* 0x08 */ - 0, 0, /* 0x09-0x0A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ - 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ - IMPLEMENTED | ALLOW_UA, /* 0x12 */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, /* 0x14 */ - IMPLEMENTED, /* 0x15 */ - 0, 0, 0, 0, /* 0x16-0x19 */ - IMPLEMENTED, /* 0x1A */ - IMPLEMENTED | CHECK_READY, /* 0x1B */ - 0, 0, /* 0x1C-0x1D */ - IMPLEMENTED | CHECK_READY, /* 0x1E */ - 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ - IMPLEMENTED | CHECK_READY, /* 0x25 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY | EARLY_ONLY,/* 0x26 */ - 0, /* 0x27 */ - IMPLEMENTED | CHECK_READY, /* 0x28 */ - 0, 0, /* 0x29-0x2A */ - IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ - 0, 0, 0, /* 0x2C-0x2E */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ - 0, 0, /* 0x40-0x41 */ - IMPLEMENTED | CHECK_READY, /* 0x42 */ - IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - IMPLEMENTED | CHECK_READY, /* 0x44 */ - IMPLEMENTED | CHECK_READY, /* 0x45 */ - IMPLEMENTED | ALLOW_UA, /* 0x46 */ - IMPLEMENTED | CHECK_READY, /* 0x47 */ - IMPLEMENTED | CHECK_READY, /* 0x48 */ - IMPLEMENTED | CHECK_READY, /* 0x49 */ - IMPLEMENTED | ALLOW_UA, /* 0x4A */ - IMPLEMENTED | CHECK_READY, /* 0x4B */ - 0, 0, /* 0x4C-0x4D */ - IMPLEMENTED | CHECK_READY, /* 0x4E */ - 0, 0, /* 0x4F-0x50 */ - IMPLEMENTED | CHECK_READY, /* 0x51 */ - IMPLEMENTED | CHECK_READY, /* 0x52 */ - 0, 0, /* 0x53-0x54 */ - IMPLEMENTED, /* 0x55 */ - 0, 0, 0, 0, /* 0x56-0x59 */ - IMPLEMENTED, /* 0x5A */ - 0, 0, 0, 0, 0, /* 0x5B-0x5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ - 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ - IMPLEMENTED | CHECK_READY, /* 0xA5 */ - 0, 0, /* 0xA6-0xA7 */ - IMPLEMENTED | CHECK_READY, /* 0xA8 */ - IMPLEMENTED | CHECK_READY, /* 0xA9 */ - 0, 0, 0, /* 0xAA-0xAC */ - IMPLEMENTED | CHECK_READY, /* 0xAD */ - 0, /* 0xAE */ - IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ - 0, 0, 0, 0, /* 0xB0-0xB3 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ - 0, 0, 0, /* 0xB5-0xB7 */ - IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ - IMPLEMENTED | CHECK_READY, /* 0xB9 */ - IMPLEMENTED | CHECK_READY, /* 0xBA */ - IMPLEMENTED, /* 0xBB */ - IMPLEMENTED | CHECK_READY, /* 0xBC */ - IMPLEMENTED, /* 0xBD */ - IMPLEMENTED | CHECK_READY, /* 0xBE */ - IMPLEMENTED | CHECK_READY, /* 0xBF */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ - 0, /* 0xC3 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ - 0, /* 0xC5 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ - 0, 0, 0, 0, 0, /* 0xC8-0xCC */ - IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ - IMPLEMENTED | SCSI_ONLY, /* 0xDA */ - 0, 0, 0, 0, 0, /* 0xDB-0xDF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ + 0, /* 0x02 */ + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + 0, 0, 0, 0, /* 0x04-0x07 */ + IMPLEMENTED | CHECK_READY, /* 0x08 */ + 0, 0, /* 0x09-0x0A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x0B */ + 0, 0, 0, 0, 0, 0, /* 0x0C-0x11 */ + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + 0, /* 0x14 */ + IMPLEMENTED, /* 0x15 */ + 0, 0, 0, 0, /* 0x16-0x19 */ + IMPLEMENTED, /* 0x1A */ + IMPLEMENTED | CHECK_READY, /* 0x1B */ + 0, 0, /* 0x1C-0x1D */ + IMPLEMENTED | CHECK_READY, /* 0x1E */ + 0, 0, 0, 0, 0, 0, /* 0x1F-0x24 */ + IMPLEMENTED | CHECK_READY, /* 0x25 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY | EARLY_ONLY, /* 0x26 */ + 0, /* 0x27 */ + IMPLEMENTED | CHECK_READY, /* 0x28 */ + 0, 0, /* 0x29-0x2A */ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x2B */ + 0, 0, 0, /* 0x2C-0x2E */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30-0x3F */ + 0, 0, /* 0x40-0x41 */ + IMPLEMENTED | CHECK_READY, /* 0x42 */ + IMPLEMENTED | CHECK_READY, /* 0x43 - Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + NOTE: The ATAPI reference says otherwise, but I think this is a question of + interpreting things right - the UNIT ATTENTION condition we have here + is a tradition from not ready to ready, by definition the drive + eventually becomes ready, make the condition go away. */ + IMPLEMENTED | CHECK_READY, /* 0x44 */ + IMPLEMENTED | CHECK_READY, /* 0x45 */ + IMPLEMENTED | ALLOW_UA, /* 0x46 */ + IMPLEMENTED | CHECK_READY, /* 0x47 */ + IMPLEMENTED | CHECK_READY, /* 0x48 */ + IMPLEMENTED | CHECK_READY, /* 0x49 */ + IMPLEMENTED | ALLOW_UA, /* 0x4A */ + IMPLEMENTED | CHECK_READY, /* 0x4B */ + 0, 0, /* 0x4C-0x4D */ + IMPLEMENTED | CHECK_READY, /* 0x4E */ + 0, 0, /* 0x4F-0x50 */ + IMPLEMENTED | CHECK_READY, /* 0x51 */ + IMPLEMENTED | CHECK_READY, /* 0x52 */ + 0, 0, /* 0x53-0x54 */ + IMPLEMENTED, /* 0x55 */ + 0, 0, 0, 0, /* 0x56-0x59 */ + IMPLEMENTED, /* 0x5A */ + 0, 0, 0, 0, 0, /* 0x5B-0x5F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x6F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x7F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80-0x8F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90-0x9F */ + 0, 0, 0, 0, 0, /* 0xA0-0xA4 */ + IMPLEMENTED | CHECK_READY, /* 0xA5 */ + 0, 0, /* 0xA6-0xA7 */ + IMPLEMENTED | CHECK_READY, /* 0xA8 */ + IMPLEMENTED | CHECK_READY, /* 0xA9 */ + 0, 0, 0, /* 0xAA-0xAC */ + IMPLEMENTED | CHECK_READY, /* 0xAD */ + 0, /* 0xAE */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + 0, 0, 0, 0, /* 0xB0-0xB3 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB4 */ + 0, 0, 0, /* 0xB5-0xB7 */ + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, /* 0xB8 */ + IMPLEMENTED | CHECK_READY, /* 0xB9 */ + IMPLEMENTED | CHECK_READY, /* 0xBA */ + IMPLEMENTED, /* 0xBB */ + IMPLEMENTED | CHECK_READY, /* 0xBC */ + IMPLEMENTED, /* 0xBD */ + IMPLEMENTED | CHECK_READY, /* 0xBE */ + IMPLEMENTED | CHECK_READY, /* 0xBF */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC0 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC1 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC2 */ + 0, /* 0xC3 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC4 */ + 0, /* 0xC5 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC6 */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xC7 */ + 0, 0, 0, 0, 0, /* 0xC8-0xCC */ + IMPLEMENTED | CHECK_READY | SCSI_ONLY, /* 0xCD */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xCE-0xD9 */ + IMPLEMENTED | SCSI_ONLY, /* 0xDA */ + 0, 0, 0, 0, 0, /* 0xDB-0xDF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0-0xEF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xF0-0xFF */ }; static uint64_t scsi_cdrom_mode_sense_page_flags = (GPMODEP_R_W_ERROR_PAGE | GPMODEP_DISCONNECT_PAGE | GPMODEP_CDROM_PAGE | GPMODEP_CDROM_AUDIO_PAGE | (1ULL << 0x0fULL) | GPMODEP_CAPABILITIES_PAGE | GPMODEP_ALL_PAGES); @@ -349,12 +349,12 @@ scsi_cdrom_init(scsi_cdrom_t *dev) dev->drv->bus_mode |= 1; scsi_cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", dev->id, dev->drv->bus_type, dev->drv->bus_mode); - dev->sense[0] = 0xf0; - dev->sense[7] = 10; + dev->sense[0] = 0xf0; + dev->sense[7] = 10; if (dev->early) - dev->status = READY_STAT | DSC_STAT; + dev->status = READY_STAT | DSC_STAT; else - dev->status = 0; + dev->status = 0; dev->pos = 0; dev->packet_status = PHASE_NONE; scsi_cdrom_sense_key = scsi_cdrom_asc = scsi_cdrom_ascq = dev->unit_attention = 0; @@ -553,7 +553,7 @@ static void scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) { int32_t bt, min_len = 0; - double dlen; + double dlen; dev->max_transfer_len = dev->request_length; @@ -570,11 +570,11 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) that a media access comand does not DRQ in the middle of a sector. One of the drivers that relies on the correctness of this behavior is MTMCDAI.SYS (the Mitsumi CD-ROM driver) for DOS which uses the READ CD command to read data on some CD types. */ - if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { - /* Round to sector length. */ - dlen = ((double) dev->max_transfer_len) / ((double) block_len); - dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; - } + if ((dev->current_cdb[0] == 0xb9) || (dev->current_cdb[0] == 0xbe)) { + /* Round to sector length. */ + dlen = ((double) dev->max_transfer_len) / ((double) block_len); + dev->max_transfer_len = ((uint16_t) floor(dlen)) * block_len; + } } else { /* Round it to the nearest 2048 bytes. */ dev->max_transfer_len = (dev->max_transfer_len >> 11) << 11; @@ -1392,14 +1392,14 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) int ret, format = 0; int real_pos, track = 0; #ifdef USE_86BOX_CD - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; - char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; #endif - int32_t blen = 0, *BufLen; - uint8_t *b; - uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; - uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; - uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; + int32_t blen = 0, *BufLen; + uint8_t *b; + uint32_t profiles[2] = { MMC_PROFILE_CD_ROM, MMC_PROFILE_DVD_ROM }; + uint8_t scsi_bus = (dev->drv->scsi_device_id >> 4) & 0x0f; + uint8_t scsi_id = dev->drv->scsi_device_id & 0x0f; if (dev->drv->bus_type == CDROM_BUS_SCSI) { BufLen = &scsi_devices[scsi_bus][scsi_id].buffer_length; @@ -2035,7 +2035,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) if (dev->early) { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); scsi_cdrom_stop(sc); - cdrom_eject(dev->id); + cdrom_eject(dev->id); scsi_cdrom_command_complete(dev); } else { scsi_cdrom_set_phase(dev, SCSI_PHASE_STATUS); @@ -2379,7 +2379,7 @@ scsi_cdrom_command(scsi_common_t *sc, uint8_t *cdb) #endif idx += 8; #ifdef USE_86BOX_CD - ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ + ide_padstr8(dev->buffer + idx, 40, device_identify_ex); /* Product */ #else if (dev->drv->bus_type == CDROM_BUS_SCSI) { if (dev->early) @@ -2722,7 +2722,7 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) { #ifdef USE_86BOX_CD scsi_cdrom_t *dev; - char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; dev = (scsi_cdrom_t *) ide->sc; @@ -2736,19 +2736,19 @@ scsi_cdrom_identify(ide_t *ide, int ide_has_dma) ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (1 << 5); /* ATAPI device, CD-ROM drive, removable media, interrupt DRQ */ else ide->buffer[0] = 0x8000 | (5 << 8) | 0x80 | (2 << 5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ - ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ + ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ #ifdef USE_86BOX_CD - ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION_EX, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ #else if (dev->early) { -#ifdef WRONG +# ifdef WRONG ide_padstr((char *) (ide->buffer + 23), "1.01 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "NEC CD-ROM DRIVE:260 ", 40); /* Model */ -#else +# else ide_padstr((char *) (ide->buffer + 23), ".110 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "EN C DCR-MOD IREV2:06 ", 40); /* Model */ -#endif +# endif } else { ide_padstr((char *) (ide->buffer + 23), "0020 ", 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), "HITACHI CDR-8130 ", 40); /* Model */ @@ -2800,7 +2800,7 @@ scsi_cdrom_drive_reset(int c) dev->drv = drv; dev->cur_lun = SCSI_LUN_USE_CDB; - dev->early = dev->drv->early; + dev->early = dev->drv->early; drv->insert = scsi_cdrom_insert; drv->get_volume = scsi_cdrom_get_volume; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 9bf8b703c..dfeae7569 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -877,8 +877,8 @@ ncr53c8xx_bad_message(ncr53c8xx_t *dev, uint8_t msg) static void ncr53c8xx_do_msgout(ncr53c8xx_t *dev, uint8_t id) { - uint8_t msg; - int len, arg; + uint8_t msg; + int len, arg; scsi_device_t *sd; sd = &scsi_devices[dev->bus][id]; @@ -2611,7 +2611,7 @@ static const device_config_t ncr53c8xx_pci_config[] = { }, }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t ncr53c810_pci_device = { diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 2e6449b7a..c4f3143e8 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -518,8 +518,7 @@ esp_dma_enable(esp_t *dev, int level) dev->dma_enabled = 1; dev->dma_86c01.status |= 0x02; timer_stop(&dev->timer); - if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && - ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { + if (((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_TI) && ((dev->rregs[ESP_CMD] & CMD_CMD) != CMD_PAD)) { timer_on_auto(&dev->timer, 40.0); } else { esp_log("Period = %lf\n", dev->period); @@ -2039,7 +2038,7 @@ static const device_config_t bios_enable_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t dc390_pci_device = { diff --git a/src/scsi/scsi_spock.c b/src/scsi/scsi_spock.c index 4ac70de43..ab970f17a 100644 --- a/src/scsi/scsi_spock.c +++ b/src/scsi/scsi_spock.c @@ -1175,7 +1175,7 @@ static const device_config_t spock_rom_config[] = { }, }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t spock_device = { diff --git a/src/sound/midi_fluidsynth.c b/src/sound/midi_fluidsynth.c index 1a66340e8..4336670c6 100644 --- a/src/sound/midi_fluidsynth.c +++ b/src/sound/midi_fluidsynth.c @@ -563,4 +563,4 @@ const device_t fluidsynth_device = { .config = fluidsynth_config }; -#endif/*USE_FLUIDSYNTH*/ +#endif /*USE_FLUIDSYNTH*/ diff --git a/src/sound/midi_mt32.c b/src/sound/midi_mt32.c index 6a917bc19..80b49112f 100644 --- a/src/sound/midi_mt32.c +++ b/src/sound/midi_mt32.c @@ -416,7 +416,7 @@ static const device_config_t mt32_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mt32_old_device = { diff --git a/src/sound/midi_rtmidi.cpp b/src/sound/midi_rtmidi.cpp index bffd0a8f2..743b828ad 100644 --- a/src/sound/midi_rtmidi.cpp +++ b/src/sound/midi_rtmidi.cpp @@ -272,7 +272,7 @@ static const device_config_t midi_input_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t rtmidi_output_device = { diff --git a/src/sound/snd_ac97_codec.c b/src/sound/snd_ac97_codec.c index 54aabab2e..58422a288 100644 --- a/src/sound/snd_ac97_codec.c +++ b/src/sound/snd_ac97_codec.c @@ -637,7 +637,7 @@ ac97_codec_get(int model) if ((model >= 0) && (model < (sizeof(ac97_codecs) / sizeof(ac97_codecs[0])))) return ac97_codecs[model].device; else - return &cs4297a_device;/* fallback */ + return &cs4297a_device; /* fallback */ } const device_t ad1881_device = { diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index 9f5a6edc5..0616e8fa6 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -1076,7 +1076,7 @@ static const device_config_t adgold_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t adgold_device = { diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 7a72d0ef0..b02243855 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -2099,7 +2099,7 @@ static const device_config_t es1371_onboard_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t es1371_device = { diff --git a/src/sound/snd_azt2316a.c b/src/sound/snd_azt2316a.c index 8a734abd0..ee46ab01b 100644 --- a/src/sound/snd_azt2316a.c +++ b/src/sound/snd_azt2316a.c @@ -1489,7 +1489,7 @@ static const device_config_t azt2316a_config[] = { .default_int = 0 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t azt2316a_device = { diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 034fa9bcf..d4a54880b 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -1474,7 +1474,7 @@ static const device_config_t cmi8738_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t cmi8338_device = { diff --git a/src/sound/snd_cms.c b/src/sound/snd_cms.c index 2014080c6..1b55765fa 100644 --- a/src/sound/snd_cms.c +++ b/src/sound/snd_cms.c @@ -227,7 +227,7 @@ static const device_config_t cms_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t cms_device = { diff --git a/src/sound/snd_cs423x.c b/src/sound/snd_cs423x.c index dceabdd08..0a98d9886 100644 --- a/src/sound/snd_cs423x.c +++ b/src/sound/snd_cs423x.c @@ -57,7 +57,7 @@ static const uint8_t slam_init_key[32] = { 0x96, 0x35, 0x9A, 0xCD, 0xE6, 0xF3, 0 0xF1, 0xF8, 0x7C, 0x3E, 0x9F, 0x4F, 0x27, 0x13, 0x09, 0x84, 0x42, 0xA1, 0xD0, 0x68, 0x34, 0x1A }; static const uint8_t cs4236b_eeprom[] = { - // clang-format off + // clang-format off /* Chip configuration */ 0x55, 0xbb, /* magic */ 0x00, 0x00, /* length */ diff --git a/src/sound/snd_emu8k.c b/src/sound/snd_emu8k.c index 33e80fb31..528a3ad50 100644 --- a/src/sound/snd_emu8k.c +++ b/src/sound/snd_emu8k.c @@ -19,17 +19,17 @@ #include <86box/timer.h> #if !defined FILTER_INITIAL && !defined FILTER_MOOG && !defined FILTER_CONSTANT -//#define FILTER_INITIAL +// #define FILTER_INITIAL # define FILTER_MOOG -//#define FILTER_CONSTANT +// #define FILTER_CONSTANT #endif #if !defined RESAMPLER_LINEAR && !defined RESAMPLER_CUBIC -//#define RESAMPLER_LINEAR +// #define RESAMPLER_LINEAR # define RESAMPLER_CUBIC #endif -//#define EMU8K_DEBUG_REGISTERS +// #define EMU8K_DEBUG_REGISTERS char *PORT_NAMES[][8] = { /* Data 0 ( 0x620/0x622) */ diff --git a/src/sound/snd_mpu401.c b/src/sound/snd_mpu401.c index 074a1396f..a31c48a7b 100644 --- a/src/sound/snd_mpu401.c +++ b/src/sound/snd_mpu401.c @@ -1958,7 +1958,7 @@ static const device_config_t mpu401_standalone_mca_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mpu401_device = { diff --git a/src/sound/snd_opl_nuked.c b/src/sound/snd_opl_nuked.c index 437ae8bc3..3c0d22131 100644 --- a/src/sound/snd_opl_nuked.c +++ b/src/sound/snd_opl_nuked.c @@ -221,7 +221,7 @@ nuked_log(const char *fmt, ...) va_start(ap, fmt); pclog_ex(fmt, ap); va_end(ap); - } + } } #else # define nuked_log(fmt, ...) diff --git a/src/sound/snd_opl_ymfm.cpp b/src/sound/snd_opl_ymfm.cpp index d1f0ed4c4..bc35c91c9 100644 --- a/src/sound/snd_opl_ymfm.cpp +++ b/src/sound/snd_opl_ymfm.cpp @@ -320,7 +320,9 @@ ymfm_drv_read(uint16_t port, void *priv) { YMFMChipBase *drv = (YMFMChipBase *) priv; - if (port == 0x381) { port += 4; } /* Point to register read port. */ + if (port == 0x381) { + port += 4; + } /* Point to register read port. */ if (drv->flags() & FLAG_CYCLES) { cycles -= ((int) (isa_timing * 8)); } @@ -337,7 +339,9 @@ ymfm_drv_write(uint16_t port, uint8_t val, void *priv) { YMFMChipBase *drv = (YMFMChipBase *) priv; ymfm_log("YMFM write port %04x value = %02x\n", port, val); - if (port == 0x380 || port == 0x381) { port += 4; } + if (port == 0x380 || port == 0x381) { + port += 4; + } drv->write(port, val); drv->update(); } diff --git a/src/sound/snd_pssj.c b/src/sound/snd_pssj.c index 80ef93e05..8b493e030 100644 --- a/src/sound/snd_pssj.c +++ b/src/sound/snd_pssj.c @@ -272,7 +272,7 @@ static const device_config_t pssj_isa_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t pssj_device = { diff --git a/src/sound/snd_sn76489.c b/src/sound/snd_sn76489.c index a29405429..3cbb44ec3 100644 --- a/src/sound/snd_sn76489.c +++ b/src/sound/snd_sn76489.c @@ -281,7 +281,7 @@ static const device_config_t tndy_config[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t sn76489_device = { diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index 5596868f2..8a325e5c3 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -264,7 +264,7 @@ static const device_config_t wss_config[] = { .default_int = 1 }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t wss_device = { diff --git a/src/unix/macOSXGlue.m b/src/unix/macOSXGlue.m index b170dea5f..95deb545d 100644 --- a/src/unix/macOSXGlue.m +++ b/src/unix/macOSXGlue.m @@ -8,36 +8,39 @@ #import -void getDefaultROMPath(char* Path) +void +getDefaultROMPath(char *Path) { - NSFileManager* sharedFM = [NSFileManager defaultManager]; - NSArray* possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory - inDomains:NSUserDomainMask]; - NSURL* appSupportDir = nil; - NSURL* appDirectory = nil; + NSFileManager *sharedFM = [NSFileManager defaultManager]; + NSArray *possibleURLs = [sharedFM URLsForDirectory:NSApplicationSupportDirectory + inDomains:NSUserDomainMask]; + NSURL *appSupportDir = nil; + NSURL *appDirectory = nil; - if ([possibleURLs count] >= 1) { - // Use the first directory (if multiple are returned) - appSupportDir = [possibleURLs objectAtIndex:0]; - } + if ([possibleURLs count] >= 1) { + // Use the first directory (if multiple are returned) + appSupportDir = [possibleURLs objectAtIndex:0]; + } - // If a valid app support directory exists, add the - // app's bundle ID to it to specify the final directory. - if (appSupportDir) { - NSString* appBundleID = [[NSBundle mainBundle] bundleIdentifier]; - appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID]; - appDirectory=[appDirectory URLByAppendingPathComponent:@"roms"]; - } + // If a valid app support directory exists, add the + // app's bundle ID to it to specify the final directory. + if (appSupportDir) { + NSString *appBundleID = [[NSBundle mainBundle] bundleIdentifier]; + appDirectory = [appSupportDir URLByAppendingPathComponent:appBundleID]; + appDirectory = [appDirectory URLByAppendingPathComponent:@"roms"]; + } // create ~/Library/Application Support/... stuff - NSError* theError = nil; - if (![sharedFM createDirectoryAtURL:appDirectory withIntermediateDirectories:YES - attributes:nil error:&theError]) - { - // Handle the error. - NSLog(@"Error creating user library rom path"); - } else NSLog(@"Create user rom path sucessfull"); + NSError *theError = nil; + if (![sharedFM createDirectoryAtURL:appDirectory + withIntermediateDirectories:YES + attributes:nil + error:&theError]) { + // Handle the error. + NSLog(@"Error creating user library rom path"); + } else + NSLog(@"Create user rom path sucessfull"); - strcpy(Path,[appDirectory fileSystemRepresentation]); - // return appDirectory; + strcpy(Path, [appDirectory fileSystemRepresentation]); + // return appDirectory; } diff --git a/src/unix/unix.c b/src/unix/unix.c index b6f617a44..cc7791a10 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -706,7 +706,7 @@ mouse_poll() mouse_y = mousedata.deltay; mouse_z = mousedata.deltaz; mousedata.deltax = mousedata.deltay = mousedata.deltaz = 0; - mouse_buttons = mousedata.mousebuttons; + mouse_buttons = mousedata.mousebuttons; SDL_UnlockMutex(mousemutex); } diff --git a/src/upi42.c b/src/upi42.c index eb0a46e1c..6937644ad 100644 --- a/src/upi42.c +++ b/src/upi42.c @@ -767,7 +767,7 @@ UPI42_COND_JMP_IMM(JNT1, !upi42->t1, ) UPI42_COND_JMP_IMM(JF0, upi42->psw & 0x20, ) UPI42_COND_JMP_IMM(JF1, upi42->sts & 0x08, ) UPI42_COND_JMP_IMM(JTF, !upi42->tf, upi42->tf = 0) -UPI42_COND_JMP_IMM(JBb, upi42->a &(1 << ((fetchdat >> 5) & 7)), ) +UPI42_COND_JMP_IMM(JBb, upi42->a & (1 << ((fetchdat >> 5) & 7)), ) UPI42_COND_JMP_IMM(JNIBF, !(upi42->sts & 0x02), ) UPI42_COND_JMP_IMM(JOBF, upi42->sts & 0x01, ) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 17272e802..c2aa2b6ad 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -216,7 +216,7 @@ typedef struct mach64_t { } accel; fifo_entry_t fifo[FIFO_SIZE]; - atomic_int fifo_read_idx, fifo_write_idx; + atomic_int fifo_read_idx, fifo_write_idx; thread_t *fifo_thread; event_t *wake_fifo_thread; diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index a49c89c18..8dba373df 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -120,7 +120,7 @@ cga_in(uint16_t addr, void *p) void cga_pravetz_out(uint16_t addr, uint8_t val, void *p) { - cga_t *cga = (cga_t *) p; + cga_t *cga = (cga_t *) p; cga->fontbase = (((unsigned int) val) << 8); } diff --git a/src/video/vid_colorplus.c b/src/video/vid_colorplus.c index 6dbb10d33..a343087d4 100644 --- a/src/video/vid_colorplus.c +++ b/src/video/vid_colorplus.c @@ -425,7 +425,7 @@ static const device_config_t colorplus_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t colorplus_device = { diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index ba18a0ba8..af1c06335 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -1305,7 +1305,7 @@ static const device_config_t ega_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t ega_device = { diff --git a/src/video/vid_et4000.c b/src/video/vid_et4000.c index 9fd02cdd3..5d0691514 100644 --- a/src/video/vid_et4000.c +++ b/src/video/vid_et4000.c @@ -822,7 +822,7 @@ static const device_config_t et4000_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t et4000_isa_device = { diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index aaa0dc223..eb604f4ea 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2791,7 +2791,7 @@ static const device_config_t et4000w32p_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t et4000w32_device = { diff --git a/src/video/vid_hercules.c b/src/video/vid_hercules.c index d141ad0e8..401166f54 100644 --- a/src/video/vid_hercules.c +++ b/src/video/vid_hercules.c @@ -641,7 +641,7 @@ static const device_config_t hercules_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t hercules_device = { diff --git a/src/video/vid_herculesplus.c b/src/video/vid_herculesplus.c index 692bcd42b..ea569cd3e 100644 --- a/src/video/vid_herculesplus.c +++ b/src/video/vid_herculesplus.c @@ -736,7 +736,7 @@ static const device_config_t herculesplus_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t herculesplus_device = { diff --git a/src/video/vid_ht216.c b/src/video/vid_ht216.c index 734e4cc90..72d101e2b 100644 --- a/src/video/vid_ht216.c +++ b/src/video/vid_ht216.c @@ -1629,17 +1629,17 @@ ht216_force_redraw(void *p) } static const device_config_t v7_vga_1024i_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 512, .selection = { - { .description = "256 kB", + { .description = "256 kB", .value = 256 }, - { .description = "512 kB", + { .description = "512 kB", .value = 512 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; // clang-format off diff --git a/src/video/vid_mda.c b/src/video/vid_mda.c index 3c88c5ccd..5ace70058 100644 --- a/src/video/vid_mda.c +++ b/src/video/vid_mda.c @@ -370,7 +370,7 @@ static const device_config_t mda_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t mda_device = { diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 8a02b65da..6da9a7c0f 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -5578,7 +5578,7 @@ static const device_config_t mystique_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t millennium_device = { diff --git a/src/video/vid_nga.c b/src/video/vid_nga.c index 8b61cd83f..86173f198 100644 --- a/src/video/vid_nga.c +++ b/src/video/vid_nga.c @@ -677,7 +677,7 @@ const device_config_t nga_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t nga_device = { diff --git a/src/video/vid_ogc.c b/src/video/vid_ogc.c index 67a278561..eddc6da8d 100644 --- a/src/video/vid_ogc.c +++ b/src/video/vid_ogc.c @@ -646,7 +646,7 @@ const device_config_t ogc_m24_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t ogc_m24_device = { diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 134947c06..3d82d459a 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -884,7 +884,7 @@ static const device_config_t paradise_wd90c30_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t paradise_wd90c30_device = { diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 089110d34..89d1505bb 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -2130,9 +2130,9 @@ pgc_ito_raster(pgc_t *dev, int32_t *x, int32_t *y) void pgc_recalctimings(pgc_t *dev) { - double disptime, _dispontime, _dispofftime; - double pixel_clock = (cpuclock / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock) * (double) (1ull << 32)); - uint8_t crtc0 = 97, crtc1 = 80; /* Values from MDA, taken from there due to the 25 MHz refresh rate. */ + double disptime, _dispontime, _dispofftime; + double pixel_clock = (cpuclock / (dev->cga_selected ? 25175000.0 : dev->native_pixel_clock) * (double) (1ull << 32)); + uint8_t crtc0 = 97, crtc1 = 80; /* Values from MDA, taken from there due to the 25 MHz refresh rate. */ /* Multiply pixel clock by 8. */ pixel_clock *= 8.0; diff --git a/src/video/vid_rtg310x.c b/src/video/vid_rtg310x.c index 66d87bb2e..10f97cf4f 100644 --- a/src/video/vid_rtg310x.c +++ b/src/video/vid_rtg310x.c @@ -380,7 +380,7 @@ static const device_config_t rtg_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t realtek_rtg3106_device = { diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index bdc982502..6c93c32f4 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -273,32 +273,32 @@ typedef struct s3_t { } accel; struct { - uint32_t nop; - uint32_t cntl; - uint32_t stretch_filt_const; - uint32_t src_dst_step; - uint32_t crop; - uint32_t src_base, dest_base; - uint32_t src, dest; - uint32_t srcbase, dstbase; - int32_t dda_init_accumulator; - int32_t k1, k2; - int dm_index; - int dither_matrix_idx; - int src_step, dst_step; - int sx, sx_backup, sy; - double cx, dx; - double cy, dy; - int sx_scale_int, sx_scale_int_backup; - double sx_scale; - double sx_scale_dec; - double sx_scale_inc; - double sx_scale_backup; - double sx_scale_len; - int dither, host_data, scale_down; - int input; - int len, start; - int odf, idf, yuv; + uint32_t nop; + uint32_t cntl; + uint32_t stretch_filt_const; + uint32_t src_dst_step; + uint32_t crop; + uint32_t src_base, dest_base; + uint32_t src, dest; + uint32_t srcbase, dstbase; + int32_t dda_init_accumulator; + int32_t k1, k2; + int dm_index; + int dither_matrix_idx; + int src_step, dst_step; + int sx, sx_backup, sy; + double cx, dx; + double cy, dy; + int sx_scale_int, sx_scale_int_backup; + double sx_scale; + double sx_scale_dec; + double sx_scale_inc; + double sx_scale_backup; + double sx_scale_len; + int dither, host_data, scale_down; + int input; + int len, start; + int odf, idf, yuv; atomic_int busy; } videoengine; @@ -876,15 +876,15 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.short_stroke = (s3->accel.short_stroke & 0xff) | (val << 8); s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } if (s3->accel.cmd & 0x1000) { s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -1417,15 +1417,15 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) s3->accel.short_stroke = val; s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } if (s3->accel.cmd & 0x1000) { s3_short_stroke_start(-1, 0, 0xffffffff, 0, s3, s3->accel.short_stroke & 0xff); @@ -6230,15 +6230,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ case 1: /*Draw line*/ if (!cpu_input) { - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.sy = s3->accel.maj_axis_pcnt; @@ -6453,15 +6453,15 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ { s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.dest = dstbase + s3->accel.cy * s3->width; @@ -6670,20 +6670,22 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; s3->accel.sy = s3->accel.multifunc[0] & 0xfff; - s3->accel.dx = s3->accel.destx_distp & 0x7ff; - if (s3->accel.destx_distp & 0x800) s3->accel.dx |= ~0x7ff; - s3->accel.dy = s3->accel.desty_axstp & 0x7ff; - if (s3->accel.desty_axstp & 0x800) s3->accel.dy |= ~0x7ff; + s3->accel.dx = s3->accel.destx_distp & 0x7ff; + if (s3->accel.destx_distp & 0x800) + s3->accel.dx |= ~0x7ff; + s3->accel.dy = s3->accel.desty_axstp & 0x7ff; + if (s3->accel.desty_axstp & 0x800) + s3->accel.dy |= ~0x7ff; - s3->accel.cx = s3->accel.cur_x & 0x7ff; - s3->accel.cy = s3->accel.cur_y & 0x7ff; + s3->accel.cx = s3->accel.cur_x & 0x7ff; + s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x & 0x800) { - s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { - s3->accel.cy |= ~0x7ff; - } + if (s3->accel.cur_x & 0x800) { + s3->accel.cx |= ~0x7ff; + } + if (s3->accel.cur_y & 0x800) { + s3->accel.cy |= ~0x7ff; + } s3->accel.src = srcbase + s3->accel.cy * s3->width; s3->accel.dest = dstbase + s3->accel.dy * s3->width; @@ -8568,83 +8570,83 @@ s3_force_redraw(void *p) } static const device_config_t s3_orchid_86c911_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 1, .selection = { - { .description = "512 KB", + { .description = "512 KB", .value = 0 }, - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; static const device_config_t s3_9fx_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 2, .selection = { - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ - { + /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ + { .description = "" } } }, - { .type = CONFIG_END} + { .type = CONFIG_END } }; static const device_config_t s3_phoenix_trio32_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 2, .selection = { - { .description = "512 KB", + { .description = "512 KB", .value = 0 }, - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; static const device_config_t s3_standard_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 4, .selection = { - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - { .description = "4 MB", + { .description = "4 MB", .value = 4 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; static const device_config_t s3_968_config[] = { - {.name = "memory", + { .name = "memory", .description = "Memory size", .type = CONFIG_SELECTION, .default_int = 4, .selection = { - { .description = "1 MB", + { .description = "1 MB", .value = 1 }, - { .description = "2 MB", + { .description = "2 MB", .value = 2 }, - { .description = "4 MB", + { .description = "4 MB", .value = 4 }, - { .description = "8 MB", + { .description = "8 MB", .value = 8 }, - { .description = "" } } }, - { .type = CONFIG_END} + { .description = "" } } }, + { .type = CONFIG_END } }; const device_t s3_orchid_86c911_isa_device = { diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index 74f301e62..99661d309 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -4587,7 +4587,7 @@ static const device_config_t s3_trio3d2x_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t s3_virge_325_pci_device = { diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 5984d9bb0..d8fa55ce3 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -946,7 +946,7 @@ device_config_t sigma_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t sigma_device = { diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index 2c37e526e..21d0b50ee 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -474,7 +474,7 @@ svga_recalctimings(svga_t *svga) svga->render = svga_render_blank; if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/ - if (svga->seqregs[1] & 8) { /*40 column*/ + if (svga->seqregs[1] & 8) { /*40 column*/ svga->render = svga_render_text_40; svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; /* Character clock is off by 1 now in 40-line modes, on all cards. */ diff --git a/src/video/vid_table.c b/src/video/vid_table.c index ed92ad2f0..ab2eb5c96 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -75,7 +75,7 @@ static const device_t vid_internal_device = { static const VIDEO_CARD video_cards[] = { -// clang-format off + // clang-format off { &vid_none_device }, { &vid_internal_device }, { &atiega_device }, @@ -261,7 +261,7 @@ video_cards[] = { { &voodoo_3_3500_se_agp_device }, { &voodoo_3_3500_si_agp_device }, { NULL } -// clang-format on + // clang-format on }; #ifdef ENABLE_VID_TABLE_LOG diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index b5f1ee72c..dd39daf8e 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -624,9 +624,9 @@ tgui_in(uint16_t addr, void *p) void tgui_recalctimings(svga_t *svga) { - tgui_t *tgui = (tgui_t *) svga->p; - uint8_t ger22lower = tgui->accel.ger22 & 0xff; - uint8_t ger22upper = (tgui->accel.ger22 >> 8); + tgui_t *tgui = (tgui_t *) svga->p; + uint8_t ger22lower = tgui->accel.ger22 & 0xff; + uint8_t ger22upper = (tgui->accel.ger22 >> 8); if (!svga->rowoffset) svga->rowoffset = 0x100; @@ -639,7 +639,7 @@ tgui_recalctimings(svga_t *svga) svga->hdisp = (svga->crtc[1] + 1) * 8; if ((tgui->accel.bpp == 3) && (ger22lower == 14) && (svga->bpp == 32) && (tgui->type == TGUI_9440)) svga->rowoffset <<= 1; - //pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset); + // pclog("Accelbpp = %d, ger22lower = %02x, ger22upper = %02x, bpp = %d, rowoffset = %d.\n", tgui->accel.bpp, ger22lower, ger22upper, svga->bpp, svga->rowoffset); } if ((svga->crtc[0x1e] & 0xA0) == 0xA0) @@ -1344,14 +1344,14 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) int x, y; int c, d; uint32_t out; - uint32_t src_dat = 0, dst_dat, pat_dat; - int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; - int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; - uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; - uint16_t *vram_w = (uint16_t *) svga->vram; - uint32_t *vram_l = (uint32_t *) svga->vram; - uint8_t ger22lower = tgui->accel.ger22 & 0xff; - uint8_t ger22upper = (tgui->accel.ger22 >> 8) & 0xff; + uint32_t src_dat = 0, dst_dat, pat_dat; + int xdir = (tgui->accel.flags & 0x200) ? -1 : 1; + int ydir = (tgui->accel.flags & 0x100) ? -1 : 1; + uint32_t trans_col = (tgui->accel.flags & TGUI_TRANSREV) ? tgui->accel.fg_col : tgui->accel.bg_col; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint32_t *vram_l = (uint32_t *) svga->vram; + uint8_t ger22lower = tgui->accel.ger22 & 0xff; + uint8_t ger22upper = (tgui->accel.ger22 >> 8) & 0xff; if (tgui->accel.bpp == 0) { trans_col &= 0xff; @@ -1439,7 +1439,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) break; } - //pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); + // pclog("TGUI accel command = %x, ger22 = %04x, hdisp = %d, dispend = %d, vtotal = %d, rowoffset = %d, svgabpp = %d, interlace = %d, accelbpp = %d, pitch = %d.\n", tgui->accel.command, tgui->accel.ger22, svga->hdisp, svga->dispend, svga->vtotal, svga->rowoffset, svga->bpp, svga->interlace, tgui->accel.bpp, tgui->accel.pitch); switch (tgui->accel.command) { case TGUI_BITBLT: @@ -1729,9 +1729,9 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } - //pclog("TGUI bres = %04x, err = %d, sizex = %d, sizey = %d, srcx = %d, srcy = %d.\n", tgui->accel.flags & 0x700, err, tgui->accel.size_x, tgui->accel.size_y, cx, tgui->accel.src_y); + // pclog("TGUI bres = %04x, err = %d, sizex = %d, sizey = %d, srcx = %d, srcy = %d.\n", tgui->accel.flags & 0x700, err, tgui->accel.size_x, tgui->accel.size_y, cx, tgui->accel.src_y); while (count-- && (tgui->accel.y <= (tgui->accel.size_y))) { - //READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { @@ -1754,7 +1754,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } if (tgui->accel.err >= (tgui->accel.size_y & 0xfff)) { - //pclog("Bres DEC: destx = %d, desty = %d, err = %d, sizey = %d.\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.err, tgui->accel.size_y); + // pclog("Bres DEC: destx = %d, desty = %d, err = %d, sizey = %d.\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.err, tgui->accel.size_y); if ((tgui->accel.src_x >= 2048) && (tgui->accel.src_x < 4096)) tgui->accel.err -= (4096 - tgui->accel.src_x); else if ((tgui->accel.src_x >= 4096) && (tgui->accel.src_x < 32768)) @@ -1789,7 +1789,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) break; } } else { - //pclog("Bres INC: desty = %d, destx = %d, err = %d, sizey = %d.\n", tgui->accel.src_y, tgui->accel.src_x, tgui->accel.err, tgui->accel.size_y); + // pclog("Bres INC: desty = %d, destx = %d, err = %d, sizey = %d.\n", tgui->accel.src_y, tgui->accel.src_x, tgui->accel.err, tgui->accel.size_y); tgui->accel.err += tgui->accel.src_y; } @@ -1850,7 +1850,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } while (count-- && (tgui->accel.y <= (tgui->accel.sv_size_y & 0xfff))) { - //READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ if ((tgui->type == TGUI_9440) || ((tgui->type >= TGUI_9660) && tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom)) { @@ -1934,7 +1934,7 @@ tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } while (count-- && (tgui->accel.y <= (tgui->accel.size_y & 0xfff))) { - //READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); + // READ(tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch), src_dat); /*Note by TC1995: I suppose the x/y clipping max is always more than 0 in the TGUI 96xx, but the TGUI 9440 lacks clipping*/ if (tgui->accel.dx >= tgui->accel.left && tgui->accel.dx <= tgui->accel.right && tgui->accel.dy >= tgui->accel.top && tgui->accel.dy <= tgui->accel.bottom) { @@ -2136,7 +2136,7 @@ tgui_accel_out(uint16_t addr, uint8_t val, void *p) break; case 0x2141: /*Size X*/ tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - tgui->accel.err = tgui->accel.size_x; + tgui->accel.err = tgui->accel.size_x; if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) tgui->accel.err -= 4096; else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) @@ -2786,7 +2786,7 @@ tgui_accel_write(uint32_t addr, uint8_t val, void *p) break; case 0x41: /*Size X*/ tgui->accel.size_x = (tgui->accel.size_x & 0xff) | (val << 8); - tgui->accel.err = tgui->accel.size_x; + tgui->accel.err = tgui->accel.size_x; if ((tgui->accel.err >= 2048) && (tgui->accel.err < 4096)) tgui->accel.err -= 4096; else if ((tgui->accel.err >= 4096) && (tgui->accel.err < 32768)) diff --git a/src/video/vid_tvga.c b/src/video/vid_tvga.c index 96931ac6f..ed249f618 100644 --- a/src/video/vid_tvga.c +++ b/src/video/vid_tvga.c @@ -31,9 +31,9 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> -#define TVGA8900B_ID 0x03 -#define TVGA9000B_ID 0x23 -#define TVGA8900CLD_ID 0x33 +#define TVGA8900B_ID 0x03 +#define TVGA9000B_ID 0x23 +#define TVGA8900CLD_ID 0x33 #define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi" #define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin" diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 43754d508..326ff9879 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -1390,7 +1390,7 @@ static const device_config_t voodoo_config[] = { { .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t voodoo_device = { diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index 9cf915d58..4170dd345 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -189,22 +189,22 @@ enum { }; enum { - cmdBaseAddr0 = 0x20, - cmdBaseSize0 = 0x24, - cmdBump0 = 0x28, - cmdRdPtrL0 = 0x2c, - cmdRdPtrH0 = 0x30, - cmdAMin0 = 0x34, - cmdAMax0 = 0x3c, - cmdStatus0 = 0x40, - cmdFifoDepth0 = 0x44, - cmdHoleCnt0 = 0x48, + cmdBaseAddr0 = 0x20, + cmdBaseSize0 = 0x24, + cmdBump0 = 0x28, + cmdRdPtrL0 = 0x2c, + cmdRdPtrH0 = 0x30, + cmdAMin0 = 0x34, + cmdAMax0 = 0x3c, + cmdStatus0 = 0x40, + cmdFifoDepth0 = 0x44, + cmdHoleCnt0 = 0x48, - Agp_agpReqSize = 0x00, - Agp_agpHostAddressLow = 0x04, - Agp_agpHostAddressHigh = 0x08, - Agp_agpGraphicsAddress = 0x0C, - Agp_agpGraphicsStride = 0x10, + Agp_agpReqSize = 0x00, + Agp_agpHostAddressLow = 0x04, + Agp_agpHostAddressHigh = 0x08, + Agp_agpGraphicsAddress = 0x0C, + Agp_agpGraphicsStride = 0x10, }; #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12) @@ -1408,7 +1408,7 @@ banshee_cmd_write(banshee_t *banshee, uint32_t addr, uint32_t val) // banshee_log("banshee_cmd_write: addr=%03x val=%08x\n", addr & 0x1fc, val); switch (addr & 0x1fc) { case Agp_agpHostAddressLow: - banshee->agpHostAddressLow = val; + banshee->agpHostAddressLow = val; break; case Agp_agpHostAddressHigh: diff --git a/src/video/vid_voodoo_banshee_blitter.c b/src/video/vid_voodoo_banshee_blitter.c index ef3b3bc1b..98f439d79 100644 --- a/src/video/vid_voodoo_banshee_blitter.c +++ b/src/video/vid_voodoo_banshee_blitter.c @@ -400,7 +400,8 @@ banshee_do_rectfill(voodoo_t *voodoo) end_command(voodoo); } -void DECODE_YUYV422(uint32_t *buf, uint8_t *src) +void +DECODE_YUYV422(uint32_t *buf, uint8_t *src) { do { int wp = 0; @@ -419,25 +420,26 @@ void DECODE_YUYV422(uint32_t *buf, uint8_t *src) dG = (88 * Cb + 183 * Cr) >> 8; dB = (453 * Cb) >> 8; - r = y1 + dR; - r = CLAMP(r); - g = y1 - dG; - g = CLAMP(g); - b = y1 + dB; - b = CLAMP(b); + r = y1 + dR; + r = CLAMP(r); + g = y1 - dG; + g = CLAMP(g); + b = y1 + dB; + b = CLAMP(b); buf[wp++] = r | (g << 8) | (b << 16); - r = y2 + dR; - r = CLAMP(r); - g = y2 - dG; - g = CLAMP(g); - b = y2 + dB; - b = CLAMP(b); + r = y2 + dR; + r = CLAMP(r); + g = y2 - dG; + g = CLAMP(g); + b = y2 + dB; + b = CLAMP(b); buf[wp++] = r | (g << 8) | (b << 16); } while (0); } -void DECODE_YUYV422_16BPP(uint16_t *buf, uint8_t *src) +void +DECODE_YUYV422_16BPP(uint16_t *buf, uint8_t *src) { do { int wp = 0; diff --git a/src/video/vid_voodoo_reg.c b/src/video/vid_voodoo_reg.c index 1b8e13022..3d5580d04 100644 --- a/src/video/vid_voodoo_reg.c +++ b/src/video/vid_voodoo_reg.c @@ -72,8 +72,8 @@ voodoo_reg_log(const char *fmt, ...) void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) { - voodoo_t *voodoo = (voodoo_t *) p; - void (*voodoo_recalc_tex)(voodoo_t *voodoo, int tmu) = NULL; + voodoo_t *voodoo = (voodoo_t *) p; + void (*voodoo_recalc_tex)(voodoo_t * voodoo, int tmu) = NULL; union { uint32_t i; float f; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index ea11b3834..84c1805ff 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2813,7 +2813,7 @@ static const device_config_t xga_configuration[] = { } }, { .name = "", .description = "", .type = CONFIG_END } -// clang-format on + // clang-format on }; const device_t xga_device = { diff --git a/src/video/video.c b/src/video/video.c index 9fed77bf2..18f2e1427 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -544,7 +544,7 @@ video_process_8_monitor(int x, int y, int monitor_index) if (monitors[monitor_index].target_buffer->line[y][xx] <= 0xff) monitors[monitor_index].target_buffer->line[y][xx] = monitors[monitor_index].mon_pal_lookup[monitors[monitor_index].target_buffer->line[y][xx]]; else - monitors[monitor_index].target_buffer->line[y][xx] = 0x00000000; + monitors[monitor_index].target_buffer->line[y][xx] = 0x00000000; } } @@ -1076,12 +1076,11 @@ loadfont_common(FILE *f, int format) (void) !fread(&fontdat12x18[c][0], 1, 36, f); break; - case 10: /* Pravetz */ + case 10: /* Pravetz */ for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */ for (d = 0; d < 8; d++) fontdat[c][d] = fgetc(f) & 0xff; break; - } (void) fclose(f); diff --git a/src/win/win.c b/src/win/win.c index 547ab4bcd..8f4c5bbcd 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -105,12 +105,13 @@ static const struct { void (*set_fs)(int fs); void (*reload)(void); } vid_apis[RENDERERS_NUM] = { - { "SDL_Software", 1, (int(*)(void*))sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_Hardware", 1, (int(*)(void*))sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, - { "SDL_OpenGL", 1, (int(*)(void*))sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload } - ,{ "OpenGL_Core", 1, (int(*)(void*))opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload} + { "SDL_Software", 1, (int (*)(void *)) sdl_inits, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "SDL_Hardware", 1, (int (*)(void *)) sdl_inith, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "SDL_OpenGL", 1, (int (*)(void *)) sdl_initho, sdl_close, NULL, sdl_pause, sdl_enable, sdl_set_fs, sdl_reload }, + { "OpenGL_Core", 1, (int (*)(void *)) opengl_init, opengl_close, opengl_resize, opengl_pause, NULL, opengl_set_fs, opengl_reload } #ifdef USE_VNC - ,{ "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } + , + { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause, NULL, NULL } #endif }; diff --git a/src/win/win_dynld.c b/src/win/win_dynld.c index 187a2b2aa..88fb632bc 100644 --- a/src/win/win_dynld.c +++ b/src/win/win_dynld.c @@ -25,11 +25,9 @@ #include <86box/86box.h> #include <86box/plat_dynld.h> - #ifdef ENABLE_DYNLD_LOG int dynld_do_log = ENABLE_DYNLD_LOG; - static void dynld_log(const char *fmt, ...) { @@ -42,46 +40,44 @@ dynld_log(const char *fmt, ...) } } #else -#define dynld_log(fmt, ...) +# define dynld_log(fmt, ...) #endif - void * dynld_module(const char *name, dllimp_t *table) { - HMODULE h; + HMODULE h; dllimp_t *imp; - void *func; + void *func; /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { dynld_log("DynLd(\"%s\"): library not found! (%08X)\n", name, GetLastError()); - return(NULL); + return (NULL); } /* Now load the desired function pointers. */ - for (imp=table; imp->name!=NULL; imp++) { + for (imp = table; imp->name != NULL; imp++) { func = GetProcAddress(h, imp->name); if (func == NULL) { dynld_log("DynLd(\"%s\"): function '%s' not found! (%08X)\n", name, imp->name, GetLastError()); FreeLibrary(h); - return(NULL); + return (NULL); } /* To overcome typing issues.. */ - *(char **)imp->func = (char *)func; + *(char **) imp->func = (char *) func; } /* All good. */ dynld_log("loaded %s\n", name); - return((void *)h); + return ((void *) h); } - void dynld_close(void *handle) { if (handle != NULL) - FreeLibrary((HMODULE)handle); + FreeLibrary((HMODULE) handle); } diff --git a/src/win/win_settings.c b/src/win/win_settings.c index d1a28bb29..afb283adc 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -2893,16 +2893,16 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM for (i = 0; i < 0x3f8; i++) fwrite(&zero, 1, 4, f); - } else if (img_format == IMG_FMT_HDX) { /* HDX file */ - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ + } else if (img_format == IMG_FMT_HDX) { /* HDX file */ + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + } else if (img_format >= IMG_FMT_VHD_FIXED) { /* VHD file */ MVHDGeom _86box_geometry; block_size = settings_get_cur_sel(hdlg, IDC_COMBO_HD_BLOCK_SIZE) == 0 ? MVHD_BLOCK_LARGE : MVHD_BLOCK_SMALL; switch (img_format) { diff --git a/src/win/win_ui.c b/src/win/win_ui.c index a68cd5808..38d7e161c 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -53,8 +53,8 @@ #define TIMER_1SEC 1 /* ID of the one-second timer */ /* Platform Public data, specific. */ -HWND hwndMain = NULL, /* application main window */ - hwndRender = NULL, /* machine render window */ +HWND hwndMain = NULL, /* application main window */ + hwndRender = NULL, /* machine render window */ hwndRender2 = NULL; /* machine second screen render window */ HMENU menuMain; /* application main menu */ RECT oldclip; /* mouse rect */ @@ -300,7 +300,7 @@ ResetAllMenus(void) CheckMenuItem(menuMain, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); if (show_second_monitors == 1) - CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_CHECKED); + CheckMenuItem(menuMain, IDM_VID_MONITORS, MF_CHECKED); if (vid_resize == 1) CheckMenuItem(menuMain, IDM_VID_RESIZE, MF_CHECKED); @@ -1380,10 +1380,10 @@ ui_init(int nCmdShow) } /* Initialize the configured Video API. */ - if (! plat_setvid(vid_api)) { + if (!plat_setvid(vid_api)) { tdconfig.pszContent = MAKEINTRESOURCE(IDS_2090); TaskDialogIndirect(&tdconfig, NULL, NULL, NULL); - return(5); + return (5); } /* Set up the current window size. */ From 9e77acf6557dbad69c91b6a886b921cbc35371d6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 19 Nov 2022 09:49:14 -0500 Subject: [PATCH 2/6] clang format in codegen & codegen_new --- src/codegen/codegen.c | 22 +- src/codegen/codegen.h | 422 +- src/codegen/codegen_accumulate.h | 7 +- src/codegen/codegen_accumulate_x86-64.c | 86 +- src/codegen/codegen_accumulate_x86.c | 80 +- src/codegen/codegen_ops.c | 4 +- src/codegen/codegen_ops.h | 32 +- src/codegen/codegen_ops_arith.h | 1834 ++- src/codegen/codegen_ops_fpu.h | 726 +- src/codegen/codegen_ops_logic.h | 1058 +- src/codegen/codegen_ops_misc.h | 469 +- src/codegen/codegen_ops_mmx.h | 406 +- src/codegen/codegen_ops_mov.h | 1135 +- src/codegen/codegen_ops_shift.h | 190 +- src/codegen/codegen_ops_stack.h | 388 +- src/codegen/codegen_ops_x86-64.h | 11193 ++++++++-------- src/codegen/codegen_ops_x86.h | 6984 +++++----- src/codegen/codegen_ops_xchg.h | 115 +- src/codegen/codegen_x86-64.c | 2146 ++- src/codegen/codegen_x86-64.h | 21 +- src/codegen/codegen_x86.c | 4072 +++--- src/codegen/codegen_x86.h | 21 +- src/codegen_new/codegen.c | 1191 +- src/codegen_new/codegen.h | 452 +- src/codegen_new/codegen_accumulate.c | 36 +- src/codegen_new/codegen_accumulate.h | 7 +- src/codegen_new/codegen_allocator.c | 182 +- src/codegen_new/codegen_allocator.h | 6 +- src/codegen_new/codegen_backend.h | 17 +- src/codegen_new/codegen_backend_arm.c | 578 +- src/codegen_new/codegen_backend_arm.h | 12 +- src/codegen_new/codegen_backend_arm64.c | 593 +- src/codegen_new/codegen_backend_arm64.h | 13 +- src/codegen_new/codegen_backend_arm64_defs.h | 212 +- src/codegen_new/codegen_backend_arm64_imm.c | 2633 ++-- src/codegen_new/codegen_backend_arm64_ops.c | 1886 +-- src/codegen_new/codegen_backend_arm64_ops.h | 10 +- src/codegen_new/codegen_backend_arm64_uops.c | 5515 ++++---- src/codegen_new/codegen_backend_arm_defs.h | 121 +- src/codegen_new/codegen_backend_arm_ops.c | 1701 +-- src/codegen_new/codegen_backend_arm_ops.h | 38 +- src/codegen_new/codegen_backend_arm_uops.c | 6273 +++++---- src/codegen_new/codegen_backend_x86-64.c | 646 +- src/codegen_new/codegen_backend_x86-64.h | 12 +- src/codegen_new/codegen_backend_x86-64_defs.h | 84 +- src/codegen_new/codegen_backend_x86-64_ops.c | 3337 +++-- .../codegen_backend_x86-64_ops_helpers.h | 151 +- .../codegen_backend_x86-64_ops_sse.c | 1202 +- src/codegen_new/codegen_backend_x86-64_uops.c | 5943 ++++---- src/codegen_new/codegen_backend_x86.c | 573 +- src/codegen_new/codegen_backend_x86.h | 12 +- src/codegen_new/codegen_backend_x86_defs.h | 38 +- src/codegen_new/codegen_backend_x86_ops.c | 2387 ++-- src/codegen_new/codegen_backend_x86_ops.h | 2 +- src/codegen_new/codegen_backend_x86_ops_fpu.c | 124 +- .../codegen_backend_x86_ops_helpers.h | 118 +- src/codegen_new/codegen_backend_x86_ops_sse.c | 989 +- src/codegen_new/codegen_backend_x86_uops.c | 5938 ++++---- src/codegen_new/codegen_block.c | 1353 +- src/codegen_new/codegen_ir.c | 312 +- src/codegen_new/codegen_ir_defs.h | 934 +- src/codegen_new/codegen_ops.h | 32 +- src/codegen_new/codegen_ops_3dnow.c | 297 +- src/codegen_new/codegen_ops_arith.c | 4415 +++--- src/codegen_new/codegen_ops_arith.h | 1 - src/codegen_new/codegen_ops_branch.c | 1885 ++- src/codegen_new/codegen_ops_fpu_arith.c | 908 +- src/codegen_new/codegen_ops_fpu_constant.c | 30 +- src/codegen_new/codegen_ops_fpu_loadstore.c | 331 +- src/codegen_new/codegen_ops_fpu_misc.c | 134 +- src/codegen_new/codegen_ops_helpers.c | 91 +- src/codegen_new/codegen_ops_helpers.h | 169 +- src/codegen_new/codegen_ops_jump.c | 435 +- src/codegen_new/codegen_ops_logic.c | 1184 +- src/codegen_new/codegen_ops_misc.c | 1042 +- src/codegen_new/codegen_ops_mmx_arith.c | 47 +- src/codegen_new/codegen_ops_mmx_cmp.c | 47 +- src/codegen_new/codegen_ops_mmx_loadstore.c | 148 +- src/codegen_new/codegen_ops_mmx_logic.c | 144 +- src/codegen_new/codegen_ops_mmx_pack.c | 47 +- src/codegen_new/codegen_ops_mmx_shift.c | 135 +- src/codegen_new/codegen_ops_mov.c | 1349 +- src/codegen_new/codegen_ops_shift.c | 2133 ++- src/codegen_new/codegen_ops_stack.c | 646 +- src/codegen_new/codegen_reg.c | 1391 +- src/codegen_new/codegen_reg.h | 568 +- 86 files changed, 46864 insertions(+), 47787 deletions(-) diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index 355653e63..f2d678067 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -16,21 +16,23 @@ void (*codegen_timing_block_start)(void); void (*codegen_timing_block_end)(void); int (*codegen_timing_jump_cycles)(void); -void codegen_timing_set(codegen_timing_t *timing) +void +codegen_timing_set(codegen_timing_t *timing) { - codegen_timing_start = timing->start; - codegen_timing_prefix = timing->prefix; - codegen_timing_opcode = timing->opcode; - codegen_timing_block_start = timing->block_start; - codegen_timing_block_end = timing->block_end; - codegen_timing_jump_cycles = timing->jump_cycles; + codegen_timing_start = timing->start; + codegen_timing_prefix = timing->prefix; + codegen_timing_opcode = timing->opcode; + codegen_timing_block_start = timing->block_start; + codegen_timing_block_end = timing->block_end; + codegen_timing_jump_cycles = timing->jump_cycles; } int codegen_in_recompile; /* This is for compatibility with new x87 code. */ -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ - cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (cpu_state.npxc & 0xc00); */ + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); } diff --git a/src/codegen/codegen.h b/src/codegen/codegen.h index a0740e27d..af602427d 100644 --- a/src/codegen/codegen.h +++ b/src/codegen/codegen.h @@ -41,11 +41,11 @@ #include "x86_ops.h" #ifdef __amd64__ -#include "codegen_x86-64.h" +# include "codegen_x86-64.h" #elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 -#include "codegen_x86.h" +# include "codegen_x86.h" #else -#error Dynamic recompiler not implemented on your platform +# error Dynamic recompiler not implemented on your platform #endif /*Handling self-modifying code (of which there is a lot on x86) : @@ -73,38 +73,37 @@ same page). */ -typedef struct codeblock_t -{ - uint64_t page_mask, page_mask2; - uint64_t *dirty_mask, *dirty_mask2; - uint64_t cmp; +typedef struct codeblock_t { + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; + uint64_t cmp; - /*Previous and next pointers, for the codeblock list associated with - each physical page. Two sets of pointers, as a codeblock can be - present in two pages.*/ - struct codeblock_t *prev, *next; - struct codeblock_t *prev_2, *next_2; + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + struct codeblock_t *prev, *next; + struct codeblock_t *prev_2, *next_2; - /*Pointers for codeblock tree, used to search for blocks when hash lookup - fails.*/ - struct codeblock_t *parent, *left, *right; + /*Pointers for codeblock tree, used to search for blocks when hash lookup + fails.*/ + struct codeblock_t *parent, *left, *right; - int pnt; - int ins; + int pnt; + int ins; int valid; - int was_recompiled; - int TOP; + int was_recompiled; + int TOP; - uint32_t pc; - uint32_t _cs; - uint32_t endpc; - uint32_t phys, phys_2; - uint32_t status; - uint32_t flags; + uint32_t pc; + uint32_t _cs; + uint32_t endpc; + uint32_t phys, phys_2; + uint32_t status; + uint32_t flags; - uint8_t data[2048]; + uint8_t data[2048]; } codeblock_t; /*Code block uses FPU*/ @@ -112,181 +111,155 @@ typedef struct codeblock_t /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) +static inline codeblock_t * +codeblock_tree_find(uint32_t phys, uint32_t _cs) { - codeblock_t *block = pages[phys >> 12].head; - uint64_t a = _cs | ((uint64_t)phys << 32); + codeblock_t *block = pages[phys >> 12].head; + uint64_t a = _cs | ((uint64_t) phys << 32); - while (block) - { - if (a == block->cmp) - { - if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) - break; - } - if (a < block->cmp) - block = block->left; - else - block = block->right; - } - - return block; -} - -static inline void codeblock_tree_add(codeblock_t *new_block) -{ - codeblock_t *block = pages[new_block->phys >> 12].head; - uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - new_block->cmp = a; - - if (!block) - { - pages[new_block->phys >> 12].head = new_block; - new_block->parent = new_block->left = new_block->right = NULL; + while (block) { + if (a == block->cmp) { + if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) + break; } + if (a < block->cmp) + block = block->left; else - { - codeblock_t *old_block = NULL; + block = block->right; + } - while (block) - { - old_block = block; - if (a < old_block->cmp) - block = block->left; - else - block = block->right; - } - - if (a < old_block->cmp) - old_block->left = new_block; - else - old_block->right = new_block; - - new_block->parent = old_block; - new_block->left = new_block->right = NULL; - } + return block; } -static inline void codeblock_tree_delete(codeblock_t *block) +static inline void +codeblock_tree_add(codeblock_t *new_block) { - codeblock_t *parent = block->parent; + codeblock_t *block = pages[new_block->phys >> 12].head; + uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32); + new_block->cmp = a; - if (!block->left && !block->right) - { - /*Easy case - remove from parent*/ - if (!parent) - pages[block->phys >> 12].head = NULL; - else - { - if (parent->left == block) - parent->left = NULL; - if (parent->right == block) - parent->right = NULL; - } - return; - } - else if (!block->left) - { - /*Only right node*/ - if (!parent) - { - pages[block->phys >> 12].head = block->right; - pages[block->phys >> 12].head->parent = NULL; - } - else - { - if (parent->left == block) - { - parent->left = block->right; - parent->left->parent = parent; - } - if (parent->right == block) - { - parent->right = block->right; - parent->right->parent = parent; - } - } - return; - } - else if (!block->right) - { - /*Only left node*/ - if (!parent) - { - pages[block->phys >> 12].head = block->left; - pages[block->phys >> 12].head->parent = NULL; - } - else - { - if (parent->left == block) - { - parent->left = block->left; - parent->left->parent = parent; - } - if (parent->right == block) - { - parent->right = block->left; - parent->right->parent = parent; - } - } - return; + if (!block) { + pages[new_block->phys >> 12].head = new_block; + new_block->parent = new_block->left = new_block->right = NULL; + } else { + codeblock_t *old_block = NULL; + + while (block) { + old_block = block; + if (a < old_block->cmp) + block = block->left; + else + block = block->right; } + + if (a < old_block->cmp) + old_block->left = new_block; else - { - /*Difficult case - node has two children. Walk right child to find lowest node*/ - codeblock_t *lowest = block->right, *highest; - codeblock_t *old_parent; + old_block->right = new_block; - while (lowest->left) - lowest = lowest->left; - - old_parent = lowest->parent; - - /*Replace deleted node with lowest node*/ - if (!parent) - pages[block->phys >> 12].head = lowest; - else - { - if (parent->left == block) - parent->left = lowest; - if (parent->right == block) - parent->right = lowest; - } - - lowest->parent = parent; - lowest->left = block->left; - if (lowest->left) - lowest->left->parent = lowest; - - old_parent->left = NULL; - - highest = lowest->right; - if (!highest) - { - if (lowest != block->right) - { - lowest->right = block->right; - block->right->parent = lowest; - } - return; - } - - while (highest->right) - highest = highest->right; - - if (block->right && block->right != lowest) - { - highest->right = block->right; - block->right->parent = highest; - } - } + new_block->parent = old_block; + new_block->left = new_block->right = NULL; + } } -#define PAGE_MASK_INDEX_MASK 3 +static inline void +codeblock_tree_delete(codeblock_t *block) +{ + codeblock_t *parent = block->parent; + + if (!block->left && !block->right) { + /*Easy case - remove from parent*/ + if (!parent) + pages[block->phys >> 12].head = NULL; + else { + if (parent->left == block) + parent->left = NULL; + if (parent->right == block) + parent->right = NULL; + } + return; + } else if (!block->left) { + /*Only right node*/ + if (!parent) { + pages[block->phys >> 12].head = block->right; + pages[block->phys >> 12].head->parent = NULL; + } else { + if (parent->left == block) { + parent->left = block->right; + parent->left->parent = parent; + } + if (parent->right == block) { + parent->right = block->right; + parent->right->parent = parent; + } + } + return; + } else if (!block->right) { + /*Only left node*/ + if (!parent) { + pages[block->phys >> 12].head = block->left; + pages[block->phys >> 12].head->parent = NULL; + } else { + if (parent->left == block) { + parent->left = block->left; + parent->left->parent = parent; + } + if (parent->right == block) { + parent->right = block->left; + parent->right->parent = parent; + } + } + return; + } else { + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = block->right, *highest; + codeblock_t *old_parent; + + while (lowest->left) + lowest = lowest->left; + + old_parent = lowest->parent; + + /*Replace deleted node with lowest node*/ + if (!parent) + pages[block->phys >> 12].head = lowest; + else { + if (parent->left == block) + parent->left = lowest; + if (parent->right == block) + parent->right = lowest; + } + + lowest->parent = parent; + lowest->left = block->left; + if (lowest->left) + lowest->left->parent = lowest; + + old_parent->left = NULL; + + highest = lowest->right; + if (!highest) { + if (lowest != block->right) { + lowest->right = block->right; + block->right->parent = lowest; + } + return; + } + + while (highest->right) + highest = highest->right; + + if (block->right && block->right != lowest) { + highest->right = block->right; + block->right->parent = highest; + } + } +} + +#define PAGE_MASK_INDEX_MASK 3 #define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_MASK 63 -#define PAGE_MASK_SHIFT 4 +#define PAGE_MASK_MASK 63 +#define PAGE_MASK_SHIFT 4 extern codeblock_t *codeblock; @@ -305,7 +278,7 @@ extern void codegen_set_op32(void); extern void codegen_flush(void); extern void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr); -extern int cpu_block_end; +extern int cpu_block_end; extern uint32_t codegen_endpc; extern int codegen_block_cycles; @@ -317,14 +290,13 @@ extern void (*codegen_timing_block_start)(void); extern void (*codegen_timing_block_end)(void); extern int (*codegen_timing_jump_cycles)(void); -typedef struct codegen_timing_t -{ - void (*start)(void); - void (*prefix)(uint8_t prefix, uint32_t fetchdat); - void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); - void (*block_start)(void); - void (*block_end)(void); - int (*jump_cycles)(void); +typedef struct codegen_timing_t { + void (*start)(void); + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); + void (*block_start)(void); + void (*block_end)(void); + int (*jump_cycles)(void); } codegen_timing_t; extern codegen_timing_t codegen_timing_pentium; @@ -342,53 +314,53 @@ extern int block_pos; #define CPU_BLOCK_END() cpu_block_end = 1 -static inline void addbyte(uint8_t val) +static inline void +addbyte(uint8_t val) { - codeblock[block_current].data[block_pos++] = val; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + codeblock[block_current].data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } -static inline void addword(uint16_t val) +static inline void +addword(uint16_t val) { uint16_t *p = (uint16_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 2; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + *p = val; + block_pos += 2; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } -static inline void addlong(uint32_t val) +static inline void +addlong(uint32_t val) { uint32_t *p = (uint32_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 4; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + *p = val; + block_pos += 4; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } -static inline void addquad(uint64_t val) +static inline void +addquad(uint64_t val) { uint64_t *p = (uint64_t *) &codeblock[block_current].data[block_pos]; - *p = val; - block_pos += 8; - if (block_pos >= BLOCK_MAX) - { - CPU_BLOCK_END(); - } + *p = val; + block_pos += 8; + if (block_pos >= BLOCK_MAX) { + CPU_BLOCK_END(); + } } /*Current physical page of block being recompiled. -1 if no recompilation taking place */ extern uint32_t recomp_page; -extern x86seg *op_ea_seg; -extern int op_ssegs; +extern x86seg *op_ea_seg; +extern int op_ssegs; extern uint32_t op_old_pc; /*Set to 1 if flags have been changed in the block being recompiled, and hence diff --git a/src/codegen/codegen_accumulate.h b/src/codegen/codegen_accumulate.h index 4d85ec0b4..3e8261748 100644 --- a/src/codegen/codegen_accumulate.h +++ b/src/codegen/codegen_accumulate.h @@ -1,8 +1,7 @@ -enum -{ - ACCREG_cycles = 0, +enum { + ACCREG_cycles = 0, - ACCREG_COUNT + ACCREG_COUNT }; struct ir_data_t; diff --git a/src/codegen/codegen_accumulate_x86-64.c b/src/codegen/codegen_accumulate_x86-64.c index e7f584f29..6e88487ba 100644 --- a/src/codegen/codegen_accumulate_x86-64.c +++ b/src/codegen/codegen_accumulate_x86-64.c @@ -9,59 +9,61 @@ static struct { - int count; - uintptr_t dest_reg; -} acc_regs[] = -{ - [ACCREG_cycles] = {0, (uintptr_t) &(cycles)}, + int count; + uintptr_t dest_reg; +} acc_regs[] = { + [ACCREG_cycles] = {0, (uintptr_t) & (cycles)}, }; -void codegen_accumulate(int acc_reg, int delta) +void +codegen_accumulate(int acc_reg, int delta) { - acc_regs[acc_reg].count += delta; + acc_regs[acc_reg].count += delta; #ifdef USE_ACYCS - if ((acc_reg == ACCREG_cycles) && (delta != 0)) { - if (delta == -1) { - /* -delta = 1 */ - addbyte(0xff); /*inc dword ptr[&acycs]*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else if (delta == 1) { - /* -delta = -1 */ - addbyte(0xff); /*dec dword ptr[&acycs]*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else { - addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &(acycs)); - addlong(-delta); - } - } + if ((acc_reg == ACCREG_cycles) && (delta != 0)) { + if (delta == -1) { + /* -delta = 1 */ + addbyte(0xff); /*inc dword ptr[&acycs]*/ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else if (delta == 1) { + /* -delta = -1 */ + addbyte(0xff); /*dec dword ptr[&acycs]*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else { + addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) & (acycs)); + addlong(-delta); + } + } #endif } -void codegen_accumulate_flush(void) +void +codegen_accumulate_flush(void) { - if (acc_regs[0].count) { - /* To reduce the size of the generated code, we take advantage of - the fact that the target offset points to _cycles within cpu_state, - so we can just use our existing infrastracture for variables - relative to cpu_state. */ - addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(acc_regs[0].count); - } + if (acc_regs[0].count) { + /* To reduce the size of the generated code, we take advantage of + the fact that the target offset points to _cycles within cpu_state, + so we can just use our existing infrastracture for variables + relative to cpu_state. */ + addbyte(0x81); /*ADDL $acc_regs[0].count,(_cycles)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addlong(acc_regs[0].count); + } - acc_regs[0].count = 0; + acc_regs[0].count = 0; } -void codegen_accumulate_reset(void) +void +codegen_accumulate_reset(void) { - acc_regs[0].count = 0; + acc_regs[0].count = 0; } diff --git a/src/codegen/codegen_accumulate_x86.c b/src/codegen/codegen_accumulate_x86.c index fb383846d..8d56c4c14 100644 --- a/src/codegen/codegen_accumulate_x86.c +++ b/src/codegen/codegen_accumulate_x86.c @@ -9,56 +9,58 @@ static struct { - int count; - uintptr_t dest_reg; -} acc_regs[] = -{ - [ACCREG_cycles] = {0, (uintptr_t) &(cycles)} + int count; + uintptr_t dest_reg; +} acc_regs[] = { + [ACCREG_cycles] = {0, (uintptr_t) & (cycles)} }; -void codegen_accumulate(int acc_reg, int delta) +void +codegen_accumulate(int acc_reg, int delta) { - acc_regs[acc_reg].count += delta; + acc_regs[acc_reg].count += delta; #ifdef USE_ACYCS - if ((acc_reg == ACCREG_cycles) && (delta != 0)) { - if (delta == -1) { - /* -delta = 1 */ - addbyte(0xff); /*inc dword ptr[&acycs]*/ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else if (delta == 1) { - /* -delta = -1 */ - addbyte(0xff); /*dec dword ptr[&acycs]*/ - addbyte(0x0d); - addlong((uint32_t) (uintptr_t) &(acycs)); - } else { - addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &(acycs)); - addlong((uintptr_t) -delta); - } - } + if ((acc_reg == ACCREG_cycles) && (delta != 0)) { + if (delta == -1) { + /* -delta = 1 */ + addbyte(0xff); /*inc dword ptr[&acycs]*/ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else if (delta == 1) { + /* -delta = -1 */ + addbyte(0xff); /*dec dword ptr[&acycs]*/ + addbyte(0x0d); + addlong((uint32_t) (uintptr_t) & (acycs)); + } else { + addbyte(0x81); /*ADD $acc_regs[c].count,acc_regs[c].dest*/ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) & (acycs)); + addlong((uintptr_t) -delta); + } + } #endif } -void codegen_accumulate_flush(void) +void +codegen_accumulate_flush(void) { - if (acc_regs[0].count) { - /* To reduce the size of the generated code, we take advantage of - the fact that the target offset points to _cycles within cpu_state, - so we can just use our existing infrastracture for variables - relative to cpu_state. */ - addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addlong(acc_regs[0].count); - } + if (acc_regs[0].count) { + /* To reduce the size of the generated code, we take advantage of + the fact that the target offset points to _cycles within cpu_state, + so we can just use our existing infrastracture for variables + relative to cpu_state. */ + addbyte(0x81); /*MOVL $acc_regs[0].count,(_cycles)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addlong(acc_regs[0].count); + } - acc_regs[0].count = 0; + acc_regs[0].count = 0; } -void codegen_accumulate_reset(void) +void +codegen_accumulate_reset(void) { - acc_regs[0].count = 0; + acc_regs[0].count = 0; } diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index aedeb88a9..a81e0c6a2 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -16,9 +16,9 @@ #include "codegen_ops.h" #if defined __amd64__ || defined _M_X64 -#include "codegen_ops_x86-64.h" +# include "codegen_ops_x86-64.h" #elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include "codegen_ops_x86.h" +# include "codegen_ops_x86.h" #endif #include "codegen_ops_arith.h" diff --git a/src/codegen/codegen_ops.h b/src/codegen/codegen_ops.h index fe54cb9a4..f92ba4f6d 100644 --- a/src/codegen/codegen_ops.h +++ b/src/codegen/codegen_ops.h @@ -26,21 +26,21 @@ extern RecompOpFn recomp_opcodes_REPNE[512]; #define REG_EBP 5 #define REG_ESI 6 #define REG_EDI 7 -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 -#define REG_AL 0 -#define REG_AH 4 -#define REG_CL 1 -#define REG_CH 5 -#define REG_DL 2 -#define REG_DH 6 -#define REG_BL 3 -#define REG_BH 7 +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 +#define REG_AL 0 +#define REG_AH 4 +#define REG_CL 1 +#define REG_CH 5 +#define REG_DL 2 +#define REG_DH 6 +#define REG_BL 3 +#define REG_BH 7 #endif diff --git a/src/codegen/codegen_ops_arith.h b/src/codegen/codegen_ops_arith.h index 2e497f17c..f1c426838 100644 --- a/src/codegen/codegen_ops_arith.h +++ b/src/codegen/codegen_ops_arith.h @@ -1,1032 +1,956 @@ -static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_W(opcode & 7); + host_reg = LOAD_REG_W(opcode & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - // ADD_HOST_REG_IMM_W(host_reg, 1); - INC_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + // ADD_HOST_REG_IMM_W(host_reg, 1); + INC_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_L(opcode & 7); + host_reg = LOAD_REG_L(opcode & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - // ADD_HOST_REG_IMM(host_reg, 1); - INC_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + // ADD_HOST_REG_IMM(host_reg, 1); + INC_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_W(opcode & 7); + host_reg = LOAD_REG_W(opcode & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - // SUB_HOST_REG_IMM_W(host_reg, 1); - DEC_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + // SUB_HOST_REG_IMM_W(host_reg, 1); + DEC_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - host_reg = LOAD_REG_L(opcode & 7); + host_reg = LOAD_REG_L(opcode & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - // SUB_HOST_REG_IMM(host_reg, 1); - DEC_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + // SUB_HOST_REG_IMM(host_reg, 1); + DEC_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); - codegen_flags_changed = 1; + codegen_flags_changed = 1; - return op_pc; + return op_pc; } -#define ROP_ARITH_RMW(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } +#define ROP_ARITH_RMW(name, op, writeback) \ + static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_B_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_W(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_W_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_L(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_L_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } -#define ROP_ARITH_RM(name, op, writeback) \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_B_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_W_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_L_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - codegen_flags_changed = 1; \ - return op_pc + 1; \ - } +#define ROP_ARITH_RM(name, op, writeback) \ + static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_B(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##8); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_B_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##16); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_W_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_##op##32); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_L_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + codegen_flags_changed = 1; \ + return op_pc + 1; \ + } ROP_ARITH_RMW(ADD, ADD, 1) ROP_ARITH_RMW(SUB, SUB, 1) ROP_ARITH_RM(ADD, ADD, 1) ROP_ARITH_RM(SUB, SUB, 1) -static uint32_t ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_B(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_B(target_seg); + src_reg = 0; + } - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -static uint32_t ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_W(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_W(target_seg); + src_reg = 0; + } - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -static uint32_t ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_L(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_L(target_seg); + src_reg = 0; + } - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_B(fetchdat & 7); + if ((fetchdat & 0xc0) == 0xc0) { + dst_reg = LOAD_REG_B(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_B(target_seg); + dst_reg = 0; + } + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + dst_reg = LOAD_REG_W(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_W(target_seg); + dst_reg = 0; + } + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + dst_reg = LOAD_REG_L(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_L(target_seg); + dst_reg = 0; + } + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, dst_reg); + dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +static uint32_t +ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; +} +static uint32_t +ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + fetchdat = fastreadl(cs + op_pc); + ADD_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 4; +} + +static uint32_t +ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; +} +static uint32_t +ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + fetchdat = fastreadl(cs + op_pc); + host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 4; +} + +static uint32_t +ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 1; +} +static uint32_t +ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; +} +static uint32_t +ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + fetchdat = fastreadl(cs + op_pc); + SUB_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + codegen_flags_changed = 1; + return op_pc + 4; +} + +static uint32_t +rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) + return 0; + + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_B(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE(target_seg); + host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - dst_reg = 0; + imm = fastreadb(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_B(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_B(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD8); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_B(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_B(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + break; + } + + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_B_RELEASE(host_reg); } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - dst_reg = 0; - } \ - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int src_reg, dst_reg; - - if ((fetchdat & 0xc0) == 0xc0) - { - dst_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - dst_reg = 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); - dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} - - -static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - ADD_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); + } else RELEASE_REG(host_reg); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 2; } -static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); +static uint32_t +rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) + return 0; + + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_W(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_W(target_seg); + host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); + } + imm = fastreadw(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_W(fetchdat & 7); + imm = (fetchdat >> 8) & 0xffff; + } + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD16); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + } + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_W_RELEASE(host_reg); + } + } else RELEASE_REG(host_reg); - codegen_flags_changed = 1; - return op_pc + 2; + codegen_flags_changed = 1; + return op_pc + 3; } -static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_L(REG_EAX); + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); + if ((fetchdat & 0x30) == 0x10) + return 0; + + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_L(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE(target_seg); + host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); + } + } else { + host_reg = LOAD_REG_L(fetchdat & 7); + } + imm = fastreadl(cs + op_pc + 1); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD32); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + } + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_L_RELEASE(host_reg); + } + } else RELEASE_REG(host_reg); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + return op_pc + 5; } -static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_B(REG_AL); + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); + if ((fetchdat & 0x30) == 0x10) + return 0; - codegen_flags_changed = 1; - return op_pc + 1; + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_W(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_W(target_seg); + host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); + } + imm = fastreadb(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_W(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } + + if (imm & 0x80) + imm |= 0xff80; + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD16); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + break; + } + + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_W_RELEASE(host_reg); + } + } else + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; } -static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_W(REG_AX); + int host_reg; + uint32_t imm; + x86seg *target_seg = NULL; - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); + if ((fetchdat & 0x30) == 0x10) + return 0; - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - fetchdat = fastreadl(cs + op_pc); - SUB_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - codegen_flags_changed = 1; - return op_pc + 4; -} - -static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - break; - } - - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_B_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} - -static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadw(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - } - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 3; -} -static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - } - imm = fastreadl(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 5; -} - -static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - break; - } - - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_W_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; -} -static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - uint32_t imm; - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) - return 0; - - if ((fetchdat & 0xc0) != 0xc0) - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - if ((fetchdat & 0x38) == 0x38) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - imm = fastreadb(cs + op_pc + 1); - } - else - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - - if (imm & 0x80) - imm |= 0xffffff80; - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); - break; - case 0x08: /*OR*/ - OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x20: /*AND*/ - AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - case 0x30: /*XOR*/ - XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - break; - case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - break; - } - - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0x38) != 0x38) - { - if ((fetchdat & 0xc0) != 0xc0) - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - else - { - STORE_REG_L_RELEASE(host_reg); - } - } - else - RELEASE_REG(host_reg); - - codegen_flags_changed = 1; - return op_pc + 2; + if ((fetchdat & 0xc0) != 0xc0) { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0x38) == 0x38) { + MEM_LOAD_ADDR_EA_L(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_L(target_seg); + host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); + } + imm = fastreadb(cs + op_pc + 1); + } else { + host_reg = LOAD_REG_L(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } + + if (imm & 0x80) + imm |= 0xffffff80; + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ADD32); + break; + case 0x08: /*OR*/ + OR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x20: /*AND*/ + AND_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x28: /*SUB*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + case 0x30: /*XOR*/ + XOR_HOST_REG_IMM(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + break; + case 0x38: /*CMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + break; + } + + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0x38) != 0x38) { + if ((fetchdat & 0xc0) != 0xc0) { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } else { + STORE_REG_L_RELEASE(host_reg); + } + } else + RELEASE_REG(host_reg); + + codegen_flags_changed = 1; + return op_pc + 2; } diff --git a/src/codegen/codegen_ops_fpu.h b/src/codegen/codegen_ops_fpu.h index 930e0182c..58a5adf7d 100644 --- a/src/codegen/codegen_ops_fpu.h +++ b/src/codegen/codegen_ops_fpu.h @@ -1,256 +1,268 @@ -static uint32_t ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFXCH(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FXCH(opcode & 7); + FP_FXCH(opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FLD(opcode & 7); + FP_FLD(opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFST(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FST(opcode & 7); + FP_FST(opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); + FP_ENTER(); - FP_FST(opcode & 7); - FP_POP(); + FP_FST(opcode & 7); + FP_POP(); - return op_pc; + return op_pc; } - -static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_LOAD_S(); + FP_LOAD_S(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_Q(target_seg); - FP_LOAD_D(); + FP_LOAD_D(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_W(target_seg); - FP_LOAD_IW(); + FP_LOAD_IW(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_L(target_seg); - FP_LOAD_IL(); + FP_LOAD_IL(); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_Q(target_seg); - FP_LOAD_IQ(); + FP_LOAD_IQ(); - codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1; + codegen_fpu_loaded_iq[(cpu_state.TOP - 1) & 7] = 1; - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg; + x86seg *target_seg; + int host_reg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = FP_LOAD_REG(0); + host_reg = FP_LOAD_REG(0); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_L(target_seg, host_reg); + MEM_STORE_ADDR_EA_L(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg1, host_reg2 = 0; + x86seg *target_seg; + int host_reg1, host_reg2 = 0; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - FP_LOAD_REG_D(0, &host_reg1, &host_reg2); + FP_LOAD_REG_D(0, &host_reg1, &host_reg2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 7); - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFSTs(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -#define ropFarith(name, size, load, op) \ -static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(FPU_ ## name); \ - \ - return op_pc + 1; \ -} +#define ropFarith(name, size, load, op) \ + static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(FPU_##name); \ + \ + return op_pc + 1; \ + } -ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -#define ropFcompare(name, size, load, op) \ -static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - x86seg *target_seg; \ - \ - FP_ENTER(); \ - op_pc--; \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - \ - CHECK_SEG_READ(target_seg); \ - load(target_seg); \ - \ - op(); \ - \ - return op_pc + 1; \ -} \ -static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \ - \ - FP_POP(); \ - \ - return new_pc; \ -} +#define ropFcompare(name, size, load, op) \ + static uint32_t ropF##name##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(); \ + \ + return op_pc + 1; \ + } \ + static uint32_t ropF##name##P##size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t new_pc = ropF##name##size(opcode, fetchdat, op_32, op_pc, block); \ + \ + FP_POP(); \ + \ + return new_pc; \ + } ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); @@ -326,320 +338,346 @@ static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc + 1; }*/ - -static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_ADD, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_ADD, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); + FP_ENTER(); + FP_COMPARE_REG(0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIV, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_DIV, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIVR, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_DIVR, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_MUL, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_MUL, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUB, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_SUB, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUBR, 0, opcode & 7); + FP_ENTER(); + FP_OP_REG(FPU_SUBR, 0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_ADD, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_DIV, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_DIVR, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_MUL, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_SUB, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); + FP_ENTER(); + FP_OP_REG(FPU_SUBR, opcode & 7, 0); - return op_pc; + return op_pc; } -static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_ADD, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_ADD, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_COMPARE_REG(0, opcode & 7); - FP_POP(); + FP_ENTER(); + FP_COMPARE_REG(0, opcode & 7); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIV, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_DIV, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_DIVR, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_DIVR, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_MUL, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_MUL, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUB, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_SUB, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_OP_REG(FPU_SUBR, opcode & 7, 0); - FP_POP(); + FP_ENTER(); + FP_OP_REG(FPU_SUBR, opcode & 7, 0); + FP_POP(); - return op_pc; + return op_pc; } -static uint32_t ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCOMPP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_COMPARE_REG(0, 1); - FP_POP2(); + FP_ENTER(); + FP_COMPARE_REG(0, 1); + FP_POP2(); - return op_pc; + return op_pc; } -static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - FP_ENTER(); - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); + FP_ENTER(); + host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxs); + STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); - return op_pc; + return op_pc; } - -static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg; + x86seg *target_seg; + int host_reg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = FP_LOAD_REG_INT_W(0); + host_reg = FP_LOAD_REG_INT_W(0); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_W(target_seg, host_reg); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg; + x86seg *target_seg; + int host_reg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = FP_LOAD_REG_INT(0); + host_reg = FP_LOAD_REG_INT(0); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_L(target_seg, host_reg); + MEM_STORE_ADDR_EA_L(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); + uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); - FP_POP(); + FP_POP(); - return new_pc; + return new_pc; } -static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; - int host_reg1, host_reg2; + x86seg *target_seg; + int host_reg1, host_reg2; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); + FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - FP_POP(); + FP_POP(); - return op_pc + 1; + return op_pc + 1; } - -static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - CHECK_SEG_READ(target_seg); + CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.npxc, 0); - UPDATE_NPXC(0); + MEM_LOAD_ADDR_EA_W(target_seg); + STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.npxc, 0); + UPDATE_NPXC(0); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; - x86seg *target_seg; + int host_reg; + x86seg *target_seg; - FP_ENTER(); - op_pc--; - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - CHECK_SEG_WRITE(target_seg); + CHECK_SEG_WRITE(target_seg); - host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxc); - MEM_STORE_ADDR_EA_W(target_seg, host_reg); + host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxc); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); - return op_pc + 1; + return op_pc + 1; } - -static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_FCHS(); + FP_ENTER(); + FP_FCHS(); - return op_pc; + return op_pc; } -#define opFLDimm(name, v) \ - static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - static double fp_imm = v; \ - \ - FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \ - \ - return op_pc; \ - } +#define opFLDimm(name, v) \ + static uint32_t ropFLD##name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + static double fp_imm = v; \ + \ + FP_ENTER(); \ + FP_LOAD_IMM_Q(*(uint64_t *) &fp_imm); \ + \ + return op_pc; \ + } opFLDimm(1, 1.0) -opFLDimm(L2T, 3.3219280948873623) -opFLDimm(L2E, 1.4426950408889634); + opFLDimm(L2T, 3.3219280948873623) + opFLDimm(L2E, 1.4426950408889634); opFLDimm(PI, 3.141592653589793); opFLDimm(EG2, 0.3010299956639812); opFLDimm(Z, 0.0) -static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) + static uint32_t ropFLDLN2(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - FP_ENTER(); - FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); + FP_ENTER(); + FP_LOAD_IMM_Q(0x3fe62e42fefa39f0ull); - return op_pc; + return op_pc; } diff --git a/src/codegen/codegen_ops_logic.h b/src/codegen/codegen_ops_logic.h index 117b19d97..55b4e117d 100644 --- a/src/codegen/codegen_ops_logic.h +++ b/src/codegen/codegen_ops_logic.h @@ -1,564 +1,540 @@ -#define ROP_LOGIC(name, op, writeback) \ - static uint32_t rop ## name ## _b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_B_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_W(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_W_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - dst_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_L(target_seg); \ - dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) \ - { \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_L_RELEASE(dst_reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ - } \ - } \ - else \ - RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_B(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_B(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); \ - op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_B_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_W(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); \ - op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_W_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } \ - static uint32_t rop ## name ## _l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int src_reg, dst_reg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - src_reg = LOAD_REG_L(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - src_reg = 0; \ - } \ - \ - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); \ - op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ - if (writeback) STORE_REG_L_RELEASE(dst_reg); \ - else RELEASE_REG(dst_reg); \ - RELEASE_REG(src_reg); \ - \ - return op_pc + 1; \ - } +#define ROP_LOGIC(name, op, writeback) \ + static uint32_t rop##name##_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_B_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_W(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_W_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + dst_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_L(target_seg); \ + dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) { \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_L_RELEASE(dst_reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, dst_reg); \ + } \ + } else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_B(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_B(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); \ + op##_HOST_REG_B(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_B_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_W(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); \ + op##_HOST_REG_W(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_W_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int src_reg, dst_reg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) { \ + src_reg = LOAD_REG_L(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + src_reg = 0; \ + } \ + \ + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); \ + op##_HOST_REG_L(dst_reg, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); \ + if (writeback) \ + STORE_REG_L_RELEASE(dst_reg); \ + else \ + RELEASE_REG(dst_reg); \ + RELEASE_REG(src_reg); \ + \ + return op_pc + 1; \ + } ROP_LOGIC(AND, AND, 1) ROP_LOGIC(OR, OR, 1) ROP_LOGIC(XOR, XOR, 1) -static uint32_t ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropTEST_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + int src_reg, dst_reg; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_B(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_B(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_B(target_seg); + src_reg = 0; + } + + dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + dst_reg = TEST_HOST_REG_B(dst_reg, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + return op_pc + 1; +} +static uint32_t +ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_W(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_W(target_seg); + src_reg = 0; + } + + dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + dst_reg = TEST_HOST_REG_W(dst_reg, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + return op_pc + 1; +} +static uint32_t +ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int src_reg, dst_reg; + + if ((fetchdat & 0xc0) == 0xc0) { + src_reg = LOAD_REG_L(fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + MEM_LOAD_ADDR_EA_L(target_seg); + src_reg = 0; + } + + dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + dst_reg = TEST_HOST_REG_L(dst_reg, src_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, dst_reg); + RELEASE_REG(dst_reg); + RELEASE_REG(src_reg); + + return op_pc + 1; +} + +static uint32_t +ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + return op_pc + 1; +} +static uint32_t +ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + return op_pc + 2; +} +static uint32_t +ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + AND_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + return op_pc + 1; +} +static uint32_t +ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + return op_pc + 2; +} +static uint32_t +ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + OR_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + return op_pc + 1; +} +static uint32_t +ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + return op_pc + 2; +} +static uint32_t +ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_B(REG_AL); + + XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_B_RELEASE(host_reg); + + return op_pc + 1; +} +static uint32_t +ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_W(REG_AX); + + XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_W_RELEASE(host_reg); + + return op_pc + 2; +} +static uint32_t +ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg = LOAD_REG_L(REG_EAX); + + fetchdat = fastreadl(cs + op_pc); + XOR_HOST_REG_IMM(host_reg, fetchdat); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + STORE_REG_L_RELEASE(host_reg); + + return op_pc + 4; +} + +static uint32_t +ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + int host_reg; + uint8_t imm; + + switch (fetchdat & 0x38) { + case 0x00: /*TEST b,#8*/ + if ((fetchdat & 0xc0) == 0xc0) { + host_reg = LOAD_REG_B(fetchdat & 7); + imm = (fetchdat >> 8) & 0xff; + } else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + imm = fastreadb(cs + op_pc + 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); MEM_LOAD_ADDR_EA_B(target_seg); - src_reg = 0; - } + host_reg = 0; + } + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN8); + host_reg = TEST_HOST_REG_IMM(host_reg, imm); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + return op_pc + 2; - dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - dst_reg = TEST_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + case 0x10: /*NOT b*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + host_reg = LOAD_REG_B(fetchdat & 7); + XOR_HOST_REG_IMM(host_reg, 0xff); + STORE_REG_B_RELEASE(host_reg); + return op_pc + 1; - return op_pc + 1; + case 0x18: /*NEG b*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB8); + host_reg = LOAD_REG_B(fetchdat & 7); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op2, host_reg); + NEG_HOST_REG_B(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op1, 0); + STORE_REG_B_RELEASE(host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + return op_pc + 1; + } + + return 0; } -static uint32_t ropTEST_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + x86seg *target_seg; + int host_reg; + uint16_t imm; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_W(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + switch (fetchdat & 0x38) { + case 0x00: /*TEST w,#*/ + if ((fetchdat & 0xc0) == 0xc0) { + host_reg = LOAD_REG_W(fetchdat & 7); + imm = (fetchdat >> 8) & 0xffff; + } else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + imm = fastreadw(cs + op_pc + 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); MEM_LOAD_ADDR_EA_W(target_seg); - src_reg = 0; - } + host_reg = 0; + } + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN16); + host_reg = TEST_HOST_REG_IMM(host_reg, imm); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + return op_pc + 3; - dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - dst_reg = TEST_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + case 0x10: /*NOT w*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + host_reg = LOAD_REG_W(fetchdat & 7); + XOR_HOST_REG_IMM(host_reg, 0xffff); + STORE_REG_W_RELEASE(host_reg); + return op_pc + 1; - return op_pc + 1; + case 0x18: /*NEG w*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB16); + host_reg = LOAD_REG_W(fetchdat & 7); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op2, host_reg); + NEG_HOST_REG_W(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op1, 0); + STORE_REG_W_RELEASE(host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + return op_pc + 1; + } + + return 0; } -static uint32_t ropTEST_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg; + x86seg *target_seg; + int host_reg; + uint32_t imm; - if ((fetchdat & 0xc0) == 0xc0) - { - src_reg = LOAD_REG_L(fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + switch (fetchdat & 0x38) { + case 0x00: /*TEST l,#*/ + if ((fetchdat & 0xc0) == 0xc0) { + host_reg = LOAD_REG_L(fetchdat & 7); + imm = fastreadl(cs + op_pc + 1); + } else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + imm = fastreadl(cs + op_pc + 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); MEM_LOAD_ADDR_EA_L(target_seg); - src_reg = 0; - } + host_reg = 0; + } + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_ZN32); + host_reg = TEST_HOST_REG_IMM(host_reg, imm); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + RELEASE_REG(host_reg); + return op_pc + 5; - dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - dst_reg = TEST_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); - RELEASE_REG(dst_reg); - RELEASE_REG(src_reg); + case 0x10: /*NOT l*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + host_reg = LOAD_REG_L(fetchdat & 7); + XOR_HOST_REG_IMM(host_reg, 0xffffffff); + STORE_REG_L_RELEASE(host_reg); + return op_pc + 1; - return op_pc + 1; -} - -static uint32_t ropAND_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xff) | 0xffffff00); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropAND_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - AND_HOST_REG_IMM(host_reg, (fetchdat & 0xffff) | 0xffff0000); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropAND_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - AND_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - OR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - OR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropTEST_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 1; -} -static uint32_t ropTEST_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 2; -} -static uint32_t ropTEST_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - host_reg = TEST_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - - return op_pc + 4; -} - -static uint32_t ropXOR_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_B(REG_AL); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_B_RELEASE(host_reg); - - return op_pc + 1; -} -static uint32_t ropXOR_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W(REG_AX); - - XOR_HOST_REG_IMM(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_W_RELEASE(host_reg); - - return op_pc + 2; -} -static uint32_t ropXOR_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_L(REG_EAX); - - fetchdat = fastreadl(cs + op_pc); - XOR_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - STORE_REG_L_RELEASE(host_reg); - - return op_pc + 4; -} - -static uint32_t ropF6(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint8_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_B(fetchdat & 7); - imm = (fetchdat >> 8) & 0xff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadb(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 2; - - case 0x10: /*NOT b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_B(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xff); - STORE_REG_B_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG b*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); - host_reg = LOAD_REG_B(fetchdat & 7); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_B(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_B_RELEASE(host_reg); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint16_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST w,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_W(fetchdat & 7); - imm = (fetchdat >> 8) & 0xffff; - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadw(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 3; - - case 0x10: /*NOT w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_W(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffff); - STORE_REG_W_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG w*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); - host_reg = LOAD_REG_W(fetchdat & 7); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_W(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_W_RELEASE(host_reg); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; -} -static uint32_t ropF7_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - x86seg *target_seg; - int host_reg; - uint32_t imm; - - switch (fetchdat & 0x38) - { - case 0x00: /*TEST l,#*/ - if ((fetchdat & 0xc0) == 0xc0) - { - host_reg = LOAD_REG_L(fetchdat & 7); - imm = fastreadl(cs + op_pc + 1); - } - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - imm = fastreadl(cs + op_pc + 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); - host_reg = TEST_HOST_REG_IMM(host_reg, imm); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - RELEASE_REG(host_reg); - return op_pc + 5; - - case 0x10: /*NOT l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - host_reg = LOAD_REG_L(fetchdat & 7); - XOR_HOST_REG_IMM(host_reg, 0xffffffff); - STORE_REG_L_RELEASE(host_reg); - return op_pc + 1; - - case 0x18: /*NEG l*/ - if ((fetchdat & 0xc0) != 0xc0) - return 0; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); - host_reg = LOAD_REG_L(fetchdat & 7); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, host_reg); - NEG_HOST_REG_L(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op1, 0); - STORE_REG_L_RELEASE(host_reg); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - return op_pc + 1; - } - - return 0; + case 0x18: /*NEG l*/ + if ((fetchdat & 0xc0) != 0xc0) + return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SUB32); + host_reg = LOAD_REG_L(fetchdat & 7); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op2, host_reg); + NEG_HOST_REG_L(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op1, 0); + STORE_REG_L_RELEASE(host_reg); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + return op_pc + 1; + } + + return 0; } diff --git a/src/codegen/codegen_ops_misc.h b/src/codegen/codegen_ops_misc.h index 9438da2d3..61854ab37 100644 --- a/src/codegen/codegen_ops_misc.h +++ b/src/codegen/codegen_ops_misc.h @@ -1,272 +1,263 @@ -static uint32_t ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropNOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - return op_pc; + return op_pc; } -static uint32_t ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCLD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - CLEAR_BITS((uintptr_t)&cpu_state.flags, D_FLAG); - return op_pc; + CLEAR_BITS((uintptr_t) &cpu_state.flags, D_FLAG); + return op_pc; } -static uint32_t ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropSTD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - SET_BITS((uintptr_t)&cpu_state.flags, D_FLAG); - return op_pc; + SET_BITS((uintptr_t) &cpu_state.flags, D_FLAG); + return op_pc; } -static uint32_t ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCLI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - CLEAR_BITS((uintptr_t)&cpu_state.flags, I_FLAG); + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + CLEAR_BITS((uintptr_t) &cpu_state.flags, I_FLAG); #ifdef CHECK_INT - CLEAR_BITS((uintptr_t)&pic_pending, 0xffffffff); + CLEAR_BITS((uintptr_t) &pic_pending, 0xffffffff); #endif - return op_pc; + return op_pc; } -static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; - SET_BITS((uintptr_t)&cpu_state.flags, I_FLAG); - return op_pc; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; + SET_BITS((uintptr_t) &cpu_state.flags, I_FLAG); + return op_pc; } -static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int host_reg; + x86seg *target_seg = NULL; + int host_reg; - if ((fetchdat & 0x30) != 0x00) - return 0; + if ((fetchdat & 0x30) != 0x00) + return 0; - CALL_FUNC((uintptr_t)flags_rebuild_c); + CALL_FUNC((uintptr_t) flags_rebuild_c); - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_B(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_B(fetchdat & 7); + else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - SAVE_EA(); - MEM_CHECK_WRITE(target_seg); - host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); - } + SAVE_EA(); + MEM_CHECK_WRITE(target_seg); + host_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); + } - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - break; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8); - STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); - break; - } + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_B(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + break; + case 0x08: /*DEC*/ + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_B(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC8); + STORE_HOST_REG_ADDR_BL((uintptr_t) &cpu_state.flags_res, host_reg); + break; + } - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_B_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_B_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_B_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; - return op_pc + 1; + return op_pc + 1; } static uint32_t codegen_temp; -static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int host_reg; + x86seg *target_seg = NULL; + int host_reg; - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_W(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_W(target_seg); - host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_W_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_W_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); - - host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR_W((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); - return op_pc + 1; - } + if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) return 0; + + if ((fetchdat & 0x30) == 0x00) + CALL_FUNC((uintptr_t) flags_rebuild_c); + + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_W(fetchdat & 7); + else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + if ((fetchdat & 0x30) != 0x00) { + MEM_LOAD_ADDR_EA_W(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_W(target_seg); + host_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); + } + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM_W(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_W_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + case 0x08: /*DEC*/ + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM_W(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC16); + STORE_HOST_REG_ADDR_WL((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_W_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_W_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + + case 0x10: /*CALL*/ + STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, host_reg); + RELEASE_REG(host_reg); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(op_pc + 1); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); + + host_reg = LOAD_VAR_W((uintptr_t) &codegen_temp); + STORE_HOST_REG_ADDR_W((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x20: /*JMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x30: /*PUSH*/ + if (!host_reg) + host_reg = LOAD_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); + return op_pc + 1; + } + return 0; } -static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int host_reg; + x86seg *target_seg = NULL; + int host_reg; - if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) - return 0; - - if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((uintptr_t)flags_rebuild_c); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_L(fetchdat & 7); - else - { - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0x30) != 0x00) - { - MEM_LOAD_ADDR_EA_L(target_seg); - host_reg = 0; - } - else - { - SAVE_EA(); - MEM_CHECK_WRITE_L(target_seg); - host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); - } - } - - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - ADD_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_L_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); - if ((fetchdat & 0xc0) == 0xc0) - STORE_REG_L_RELEASE(host_reg); - else - { - LOAD_EA(); - MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); - } - codegen_flags_changed = 1; - return op_pc + 1; - - case 0x10: /*CALL*/ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, host_reg); - RELEASE_REG(host_reg); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc + 1); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); - - host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x20: /*JMP*/ - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, host_reg); - return -1; - - case 0x30: /*PUSH*/ - if (!host_reg) - host_reg = LOAD_HOST_REG(host_reg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); - return op_pc + 1; - } + if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) return 0; + + if ((fetchdat & 0x30) == 0x00) + CALL_FUNC((uintptr_t) flags_rebuild_c); + + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_L(fetchdat & 7); + else { + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + if ((fetchdat & 0x30) != 0x00) { + MEM_LOAD_ADDR_EA_L(target_seg); + host_reg = 0; + } else { + SAVE_EA(); + MEM_CHECK_WRITE_L(target_seg); + host_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); + } + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + ADD_HOST_REG_IMM(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_INC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_L_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + case 0x08: /*DEC*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_op1, host_reg); + SUB_HOST_REG_IMM(host_reg, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_DEC32); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.flags_res, host_reg); + if ((fetchdat & 0xc0) == 0xc0) + STORE_REG_L_RELEASE(host_reg); + else { + LOAD_EA(); + MEM_STORE_ADDR_EA_L_NO_ABRT(target_seg, host_reg); + } + codegen_flags_changed = 1; + return op_pc + 1; + + case 0x10: /*CALL*/ + STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, host_reg); + RELEASE_REG(host_reg); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(op_pc + 1); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); + + host_reg = LOAD_VAR_L((uintptr_t) &codegen_temp); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x20: /*JMP*/ + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, host_reg); + return -1; + + case 0x30: /*PUSH*/ + if (!host_reg) + host_reg = LOAD_HOST_REG(host_reg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); + return op_pc + 1; + } + return 0; } diff --git a/src/codegen/codegen_ops_mmx.h b/src/codegen/codegen_ops_mmx.h index 4cdb080fb..edb5b0586 100644 --- a/src/codegen/codegen_ops_mmx.h +++ b/src/codegen/codegen_ops_mmx.h @@ -1,277 +1,267 @@ -static uint32_t ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVQ_q_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg1, host_reg2 = 0; + int host_reg1, host_reg2 = 0; - MMX_ENTER(); + MMX_ENTER(); - LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2); + LOAD_MMX_Q((fetchdat >> 3) & 7, &host_reg1, &host_reg2); - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_MMX_Q(fetchdat & 7, host_reg1, host_reg2); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 7); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 7); - MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); - } + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVQ_mm_q(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - MMX_ENTER(); + MMX_ENTER(); - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg1, host_reg2; + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg1, host_reg2; - LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2); - STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + LOAD_MMX_Q(fetchdat & 7, &host_reg1, &host_reg2); + STORE_MMX_Q((fetchdat >> 3) & 7, host_reg1, host_reg2); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); + CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_Q(target_seg); - STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2); - } + MEM_LOAD_ADDR_EA_Q(target_seg); + STORE_MMX_Q((fetchdat >> 3) & 7, LOAD_Q_REG_1, LOAD_Q_REG_2); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVD_l_mm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - MMX_ENTER(); + MMX_ENTER(); - host_reg = LOAD_MMX_D((fetchdat >> 3) & 7); + host_reg = LOAD_MMX_D((fetchdat >> 3) & 7); - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 3); - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - } + MEM_STORE_ADDR_EA_L(target_seg, host_reg); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOVD_mm_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - MMX_ENTER(); + MMX_ENTER(); - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_L(fetchdat & 7); + STORE_MMX_LQ((fetchdat >> 3) & 7, host_reg); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); + CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_MMX_LQ((fetchdat >> 3) & 7, 0); - } + MEM_LOAD_ADDR_EA_L(target_seg); + STORE_MMX_LQ((fetchdat >> 3) & 7, 0); + } - return op_pc + 1; + return op_pc + 1; } #define MMX_OP(name, func) \ -static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ + static uint32_t name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ int src_reg1, src_reg2; \ int xmm_src, xmm_dst; \ \ MMX_ENTER(); \ \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ - } \ - else \ - { \ - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + xmm_src = LOAD_MMX_Q_MMX(fetchdat & 7); \ + } else { \ + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ \ - CHECK_SEG_READ(target_seg); \ + CHECK_SEG_READ(target_seg); \ \ - MEM_LOAD_ADDR_EA_Q(target_seg); \ - src_reg1 = LOAD_Q_REG_1; \ - src_reg2 = LOAD_Q_REG_2; \ - xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ + MEM_LOAD_ADDR_EA_Q(target_seg); \ + src_reg1 = LOAD_Q_REG_1; \ + src_reg2 = LOAD_Q_REG_2; \ + xmm_src = LOAD_INT_TO_MMX(src_reg1, src_reg2); \ } \ xmm_dst = LOAD_MMX_Q_MMX((fetchdat >> 3) & 7); \ - func(xmm_dst, xmm_src); \ + func(xmm_dst, xmm_src); \ STORE_MMX_Q_MMX((fetchdat >> 3) & 7, xmm_dst); \ \ return op_pc + 1; \ -} + } -MMX_OP(ropPAND, MMX_AND) +MMX_OP(ropPAND, MMX_AND) MMX_OP(ropPANDN, MMX_ANDN) -MMX_OP(ropPOR, MMX_OR) -MMX_OP(ropPXOR, MMX_XOR) +MMX_OP(ropPOR, MMX_OR) +MMX_OP(ropPXOR, MMX_XOR) -MMX_OP(ropPADDB, MMX_ADDB) -MMX_OP(ropPADDW, MMX_ADDW) -MMX_OP(ropPADDD, MMX_ADDD) -MMX_OP(ropPADDSB, MMX_ADDSB) -MMX_OP(ropPADDSW, MMX_ADDSW) -MMX_OP(ropPADDUSB, MMX_ADDUSB) -MMX_OP(ropPADDUSW, MMX_ADDUSW) +MMX_OP(ropPADDB, MMX_ADDB) +MMX_OP(ropPADDW, MMX_ADDW) +MMX_OP(ropPADDD, MMX_ADDD) +MMX_OP(ropPADDSB, MMX_ADDSB) +MMX_OP(ropPADDSW, MMX_ADDSW) +MMX_OP(ropPADDUSB, MMX_ADDUSB) +MMX_OP(ropPADDUSW, MMX_ADDUSW) -MMX_OP(ropPSUBB, MMX_SUBB) -MMX_OP(ropPSUBW, MMX_SUBW) -MMX_OP(ropPSUBD, MMX_SUBD) -MMX_OP(ropPSUBSB, MMX_SUBSB) -MMX_OP(ropPSUBSW, MMX_SUBSW) -MMX_OP(ropPSUBUSB, MMX_SUBUSB) -MMX_OP(ropPSUBUSW, MMX_SUBUSW) +MMX_OP(ropPSUBB, MMX_SUBB) +MMX_OP(ropPSUBW, MMX_SUBW) +MMX_OP(ropPSUBD, MMX_SUBD) +MMX_OP(ropPSUBSB, MMX_SUBSB) +MMX_OP(ropPSUBSW, MMX_SUBSW) +MMX_OP(ropPSUBUSB, MMX_SUBUSB) +MMX_OP(ropPSUBUSW, MMX_SUBUSW) MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW); MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD); MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ); -MMX_OP(ropPACKSSWB, MMX_PACKSSWB); -MMX_OP(ropPCMPGTB, MMX_PCMPGTB); -MMX_OP(ropPCMPGTW, MMX_PCMPGTW); -MMX_OP(ropPCMPGTD, MMX_PCMPGTD); -MMX_OP(ropPACKUSWB, MMX_PACKUSWB); +MMX_OP(ropPACKSSWB, MMX_PACKSSWB); +MMX_OP(ropPCMPGTB, MMX_PCMPGTB); +MMX_OP(ropPCMPGTW, MMX_PCMPGTW); +MMX_OP(ropPCMPGTD, MMX_PCMPGTD); +MMX_OP(ropPACKUSWB, MMX_PACKUSWB); MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW); MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD); MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ); -MMX_OP(ropPACKSSDW, MMX_PACKSSDW); +MMX_OP(ropPACKSSDW, MMX_PACKSSDW); -MMX_OP(ropPCMPEQB, MMX_PCMPEQB); -MMX_OP(ropPCMPEQW, MMX_PCMPEQW); -MMX_OP(ropPCMPEQD, MMX_PCMPEQD); +MMX_OP(ropPCMPEQB, MMX_PCMPEQB); +MMX_OP(ropPCMPEQW, MMX_PCMPEQW); +MMX_OP(ropPCMPEQD, MMX_PCMPEQD); -MMX_OP(ropPSRLW, MMX_PSRLW) -MMX_OP(ropPSRLD, MMX_PSRLD) -MMX_OP(ropPSRLQ, MMX_PSRLQ) -MMX_OP(ropPSRAW, MMX_PSRAW) -MMX_OP(ropPSRAD, MMX_PSRAD) -MMX_OP(ropPSLLW, MMX_PSLLW) -MMX_OP(ropPSLLD, MMX_PSLLD) -MMX_OP(ropPSLLQ, MMX_PSLLQ) +MMX_OP(ropPSRLW, MMX_PSRLW) +MMX_OP(ropPSRLD, MMX_PSRLD) +MMX_OP(ropPSRLQ, MMX_PSRLQ) +MMX_OP(ropPSRAW, MMX_PSRAW) +MMX_OP(ropPSRAD, MMX_PSRAD) +MMX_OP(ropPSLLW, MMX_PSLLW) +MMX_OP(ropPSLLD, MMX_PSLLD) +MMX_OP(ropPSLLQ, MMX_PSLLQ) -MMX_OP(ropPMULLW, MMX_PMULLW); -MMX_OP(ropPMULHW, MMX_PMULHW); -MMX_OP(ropPMADDWD, MMX_PMADDWD); +MMX_OP(ropPMULLW, MMX_PMULLW); +MMX_OP(ropPMULHW, MMX_PMULHW); +MMX_OP(ropPMADDWD, MMX_PMADDWD); -static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLW*/ - MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAW*/ - MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLW*/ - MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLD*/ - MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAD*/ - MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLD*/ - MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} -static uint32_t ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int xmm_dst; - - if ((fetchdat & 0xc0) != 0xc0) - return 0; - if ((fetchdat & 0x08) || !(fetchdat & 0x30)) - return 0; - - MMX_ENTER(); - - xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); - switch (fetchdat & 0x38) - { - case 0x10: /*PSRLQ*/ - MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x20: /*PSRAQ*/ - MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - case 0x30: /*PSLLQ*/ - MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); - break; - } - STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); - - return op_pc + 2; -} - -static uint32_t ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - codegen_mmx_entered = 0; + int xmm_dst; + if ((fetchdat & 0xc0) != 0xc0) return 0; + if ((fetchdat & 0x08) || !(fetchdat & 0x30)) + return 0; + + MMX_ENTER(); + + xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); + switch (fetchdat & 0x38) { + case 0x10: /*PSRLW*/ + MMX_PSRLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x20: /*PSRAW*/ + MMX_PSRAW_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x30: /*PSLLW*/ + MMX_PSLLW_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + } + STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); + + return op_pc + 2; +} +static uint32_t +ropPSxxD_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int xmm_dst; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + if ((fetchdat & 0x08) || !(fetchdat & 0x30)) + return 0; + + MMX_ENTER(); + + xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); + switch (fetchdat & 0x38) { + case 0x10: /*PSRLD*/ + MMX_PSRLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x20: /*PSRAD*/ + MMX_PSRAD_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x30: /*PSLLD*/ + MMX_PSLLD_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + } + STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); + + return op_pc + 2; +} +static uint32_t +ropPSxxQ_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int xmm_dst; + + if ((fetchdat & 0xc0) != 0xc0) + return 0; + if ((fetchdat & 0x08) || !(fetchdat & 0x30)) + return 0; + + MMX_ENTER(); + + xmm_dst = LOAD_MMX_Q_MMX(fetchdat & 7); + switch (fetchdat & 0x38) { + case 0x10: /*PSRLQ*/ + MMX_PSRLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x20: /*PSRAQ*/ + MMX_PSRAQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + case 0x30: /*PSLLQ*/ + MMX_PSLLQ_imm(xmm_dst, (fetchdat >> 8) & 0xff); + break; + } + STORE_MMX_Q_MMX(fetchdat & 7, xmm_dst); + + return op_pc + 2; +} + +static uint32_t +ropEMMS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + codegen_mmx_entered = 0; + + return 0; } diff --git a/src/codegen/codegen_ops_mov.h b/src/codegen/codegen_ops_mov.h index df7a6a31b..f5e61eb60 100644 --- a/src/codegen/codegen_ops_mov.h +++ b/src/codegen/codegen_ops_mov.h @@ -1,653 +1,620 @@ -static uint32_t ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_rb_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); + STORE_IMM_REG_B(opcode & 7, fetchdat & 0xff); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_rw_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); + STORE_IMM_REG_W(opcode & 7, fetchdat & 0xffff); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_rl_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - fetchdat = fastreadl(cs + op_pc); + fetchdat = fastreadl(cs + op_pc); - STORE_IMM_REG_L(opcode & 7, fetchdat); + STORE_IMM_REG_L(opcode & 7, fetchdat); - return op_pc + 4; + return op_pc + 4; } - -static uint32_t ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_b_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); + int host_reg = LOAD_REG_B((fetchdat >> 3) & 7); - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_B_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 0); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 0); - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - host_reg = LOAD_REG_L((fetchdat >> 3) & 7); - - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 3); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - - } - - return op_pc + 1; -} - -static uint32_t ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_L(fetchdat & 7); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_L(target_seg); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadb(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_B(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 2; -} -static uint32_t ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadw(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 3; -} -static uint32_t ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - uint32_t imm = fastreadl(cs + op_pc + 1); - - STORE_IMM_REG_L(fetchdat & 7, imm); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - uint32_t imm = fastreadl(cs + op_pc + 1); - int host_reg = LOAD_REG_IMM(imm); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - CHECK_SEG_WRITE(target_seg); - - MEM_STORE_ADDR_EA_L(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 5; -} - - -static uint32_t ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr); - STORE_REG_TARGET_B_RELEASE(0, REG_AL); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr); - STORE_REG_TARGET_W_RELEASE(0, REG_AX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -static uint32_t ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_READ(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr); - STORE_REG_TARGET_L_RELEASE(0, REG_EAX); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -static uint32_t ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - uint32_t addr; - int host_reg; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - host_reg = LOAD_REG_B(REG_AL); - - MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg); + MEM_STORE_ADDR_EA_B(target_seg, host_reg); RELEASE_REG(host_reg); + } - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + 1; } -static uint32_t ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_w_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t addr; - int host_reg; + int host_reg = LOAD_REG_W((fetchdat >> 3) & 7); - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - host_reg = LOAD_REG_W(REG_AX); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 1); - MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); RELEASE_REG(host_reg); + } - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + 1; } -static uint32_t ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) + +static uint32_t +ropMOV_l_r(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t addr; - int host_reg; + int host_reg; - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); + host_reg = LOAD_REG_L((fetchdat >> 3) & 7); - CHECK_SEG_WRITE(op_ea_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + if ((fetchdat & 0xc0) == 0xc0) { + STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - host_reg = LOAD_REG_L(REG_EAX); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 3); + + MEM_STORE_ADDR_EA_L(target_seg, host_reg); RELEASE_REG(host_reg); + } - return op_pc + ((op_32 & 0x200) ? 4 : 2); + return op_pc + 1; } -static uint32_t ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_r_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int dest_reg = (fetchdat >> 3) & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + STORE_REG_TARGET_B_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - if ((fetchdat & 0xc0) == 0xc0) - return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + CHECK_SEG_READ(target_seg); - STORE_REG_TARGET_W_RELEASE(0, dest_reg); + MEM_LOAD_ADDR_EA_B(target_seg); + STORE_REG_TARGET_B_RELEASE(0, (fetchdat >> 3) & 7); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_r_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int dest_reg = (fetchdat >> 3) & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_W(fetchdat & 7); + STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - if ((fetchdat & 0xc0) == 0xc0) - return 0; + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + CHECK_SEG_READ(target_seg); - STORE_REG_TARGET_L_RELEASE(0, dest_reg); + MEM_LOAD_ADDR_EA_W(target_seg); + STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); + } - return op_pc + 1; + return op_pc + 1; +} +static uint32_t +ropMOV_r_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_L(fetchdat & 7); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_L(target_seg); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; } -static uint32_t ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_b_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } + if ((fetchdat & 0xc0) == 0xc0) { + STORE_IMM_REG_B(fetchdat & 7, (fetchdat >> 8) & 0xff); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + uint32_t imm = fastreadb(cs + op_pc + 1); + int host_reg = LOAD_REG_IMM(imm); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_B(target_seg, host_reg); + RELEASE_REG(host_reg); + } + + return op_pc + 2; +} +static uint32_t +ropMOV_w_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + STORE_IMM_REG_W(fetchdat & 7, (fetchdat >> 8) & 0xffff); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + uint32_t imm = fastreadw(cs + op_pc + 1); + int host_reg = LOAD_REG_IMM(imm); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_W(target_seg, host_reg); + RELEASE_REG(host_reg); + } + + return op_pc + 3; +} +static uint32_t +ropMOV_l_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + uint32_t imm = fastreadl(cs + op_pc + 1); + + STORE_IMM_REG_L(fetchdat & 7, imm); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + uint32_t imm = fastreadl(cs + op_pc + 1); + int host_reg = LOAD_REG_IMM(imm); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_L(target_seg, host_reg); + RELEASE_REG(host_reg); + } + + return op_pc + 5; +} + +static uint32_t +ropMOV_AL_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_READ(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + MEM_LOAD_ADDR_IMM_B(op_ea_seg, addr); + STORE_REG_TARGET_B_RELEASE(0, REG_AL); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_AX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_READ(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + MEM_LOAD_ADDR_IMM_W(op_ea_seg, addr); + STORE_REG_TARGET_W_RELEASE(0, REG_AX); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_EAX_a(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_READ(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + MEM_LOAD_ADDR_IMM_L(op_ea_seg, addr); + STORE_REG_TARGET_L_RELEASE(0, REG_EAX); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} + +static uint32_t +ropMOV_a_AL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + int host_reg; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_WRITE(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + host_reg = LOAD_REG_B(REG_AL); + + MEM_STORE_ADDR_IMM_B(op_ea_seg, addr, host_reg); + RELEASE_REG(host_reg); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_a_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + int host_reg; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_WRITE(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + host_reg = LOAD_REG_W(REG_AX); + + MEM_STORE_ADDR_IMM_W(op_ea_seg, addr, host_reg); + RELEASE_REG(host_reg); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} +static uint32_t +ropMOV_a_EAX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t addr; + int host_reg; + + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); + + CHECK_SEG_WRITE(op_ea_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + host_reg = LOAD_REG_L(REG_EAX); + + MEM_STORE_ADDR_IMM_L(op_ea_seg, addr, host_reg); + RELEASE_REG(host_reg); + + return op_pc + ((op_32 & 0x200) ? 4 : 2); +} + +static uint32_t +ropLEA_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + return 0; + + FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_REG_TARGET_W_RELEASE(0, dest_reg); + + return op_pc + 1; +} +static uint32_t +ropLEA_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int dest_reg = (fetchdat >> 3) & 7; + + if ((fetchdat & 0xc0) == 0xc0) + return 0; + + FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_REG_TARGET_L_RELEASE(0, dest_reg); + + return op_pc + 1; +} + +static uint32_t +ropMOVZX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = ZERO_EXTEND_W_B(host_reg); + STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + ZERO_EXTEND_W_B(0); + STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = ZERO_EXTEND_L_B(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + ZERO_EXTEND_L_B(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_W(fetchdat & 7); + host_reg = ZERO_EXTEND_L_W(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_W(target_seg); + ZERO_EXTEND_L_W(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} + +static uint32_t +ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = SIGN_EXTEND_W_B(host_reg); + STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + SIGN_EXTEND_W_B(0); + STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_B(fetchdat & 7); + host_reg = SIGN_EXTEND_L_B(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_B(target_seg); + SIGN_EXTEND_L_B(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} +static uint32_t +ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int host_reg = LOAD_REG_W(fetchdat & 7); + host_reg = SIGN_EXTEND_L_W(host_reg); + STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_W(target_seg); + SIGN_EXTEND_L_W(0); + STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); + } + + return op_pc + 1; +} + +static uint32_t +ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + host_reg = LOAD_VAR_WL((uintptr_t) &ES); + break; + case 0x08: /*CS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &CS); + break; + case 0x18: /*DS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &DS); + break; + case 0x10: /*SS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &SS); + break; + case 0x20: /*FS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &FS); + break; + case 0x28: /*GS*/ + host_reg = LOAD_VAR_WL((uintptr_t) &GS); + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) { + if (op_32 & 0x100) + STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); + } else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - CHECK_SEG_READ(target_seg); + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 1); - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } + MEM_STORE_ADDR_EA_W(target_seg, host_reg); + RELEASE_REG(host_reg); + } - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVZX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = ZERO_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + case 0x18: /*DS*/ + case 0x20: /*FS*/ + case 0x28: /*GS*/ + break; + case 0x10: /*SS*/ + default: + return 0; + } - CHECK_SEG_READ(target_seg); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); - MEM_LOAD_ADDR_EA_B(target_seg); - ZERO_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } + if ((fetchdat & 0xc0) == 0xc0) + host_reg = LOAD_REG_W(fetchdat & 7); + else { + x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - return op_pc + 1; -} -static uint32_t ropMOVZX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = ZERO_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_W(target_seg); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); + host_reg = 0; + } - CHECK_SEG_READ(target_seg); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + LOAD_SEG(host_reg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + LOAD_SEG(host_reg, &cpu_state.seg_ds); + break; + case 0x20: /*FS*/ + LOAD_SEG(host_reg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + LOAD_SEG(host_reg, &cpu_state.seg_gs); + break; + } - MEM_LOAD_ADDR_EA_W(target_seg); - ZERO_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropMOVSX_w_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_W_B(host_reg); - STORE_REG_TARGET_W_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_W_B(0); - STORE_REG_TARGET_W_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_B(fetchdat & 7); - host_reg = SIGN_EXTEND_L_B(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_B(target_seg); - SIGN_EXTEND_L_B(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} -static uint32_t ropMOVSX_l_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int host_reg = LOAD_REG_W(fetchdat & 7); - host_reg = SIGN_EXTEND_L_W(host_reg); - STORE_REG_TARGET_L_RELEASE(host_reg, (fetchdat >> 3) & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_READ(target_seg); - - MEM_LOAD_ADDR_EA_W(target_seg); - SIGN_EXTEND_L_W(0); - STORE_REG_TARGET_L_RELEASE(0, (fetchdat >> 3) & 7); - } - - return op_pc + 1; -} - -static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - host_reg = LOAD_VAR_WL((uintptr_t)&ES); - break; - case 0x08: /*CS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&CS); - break; - case 0x18: /*DS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&DS); - break; - case 0x10: /*SS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&SS); - break; - case 0x20: /*FS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&FS); - break; - case 0x28: /*GS*/ - host_reg = LOAD_VAR_WL((uintptr_t)&GS); - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - if (op_32 & 0x100) - STORE_REG_TARGET_L_RELEASE(host_reg, fetchdat & 7); - else - STORE_REG_TARGET_W_RELEASE(host_reg, fetchdat & 7); - } - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - CHECK_SEG_WRITE(target_seg); - CHECK_SEG_LIMITS(target_seg, 1); - - MEM_STORE_ADDR_EA_W(target_seg, host_reg); - RELEASE_REG(host_reg); - } - - return op_pc + 1; -} -static uint32_t ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) -{ - int host_reg; - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - case 0x18: /*DS*/ - case 0x20: /*FS*/ - case 0x28: /*GS*/ - break; - case 0x10: /*SS*/ - default: - return 0; - } - - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - - if ((fetchdat & 0xc0) == 0xc0) - host_reg = LOAD_REG_W(fetchdat & 7); - else - { - x86seg *target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); - - CHECK_SEG_READ(target_seg); - MEM_LOAD_ADDR_EA_W(target_seg); - - host_reg = 0; - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - LOAD_SEG(host_reg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - LOAD_SEG(host_reg, &cpu_state.seg_ds); - break; - case 0x20: /*FS*/ - LOAD_SEG(host_reg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - LOAD_SEG(host_reg, &cpu_state.seg_gs); - break; - } - - return op_pc + 1; -} - -#define ropLseg(seg, rseg) \ -static uint32_t ropL ## seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - x86seg *target_seg; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - SAVE_EA(); \ - \ - if (op_32 & 0x100) \ - { \ - MEM_LOAD_ADDR_EA_L(target_seg); \ - STORE_HOST_REG_ADDR((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ - } \ - else \ - { \ - MEM_LOAD_ADDR_EA_W(target_seg); \ - STORE_HOST_REG_ADDR_W((uintptr_t)&codegen_temp, 0); \ - LOAD_EA(); \ - MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ - } \ - LOAD_SEG(0, &rseg); \ - if (op_32 & 0x100) \ - { \ - \ - int host_reg = LOAD_VAR_L((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \ - } \ - else \ - { \ - int host_reg = LOAD_VAR_W((uintptr_t)&codegen_temp); \ - STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \ - } \ - \ - if (&rseg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \ - return op_pc + 1; \ -} +#define ropLseg(seg, rseg) \ + static uint32_t ropL##seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + x86seg *target_seg; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + SAVE_EA(); \ + \ + if (op_32 & 0x100) { \ + MEM_LOAD_ADDR_EA_L(target_seg); \ + STORE_HOST_REG_ADDR((uintptr_t) &codegen_temp, 0); \ + LOAD_EA(); \ + MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 4); \ + } else { \ + MEM_LOAD_ADDR_EA_W(target_seg); \ + STORE_HOST_REG_ADDR_W((uintptr_t) &codegen_temp, 0); \ + LOAD_EA(); \ + MEM_LOAD_ADDR_EA_W_OFFSET(target_seg, 2); \ + } \ + LOAD_SEG(0, &rseg); \ + if (op_32 & 0x100) { \ + \ + int host_reg = LOAD_VAR_L((uintptr_t) &codegen_temp); \ + STORE_REG_TARGET_L_RELEASE(host_reg, dest_reg); \ + } else { \ + int host_reg = LOAD_VAR_W((uintptr_t) &codegen_temp); \ + STORE_REG_TARGET_W_RELEASE(host_reg, dest_reg); \ + } \ + \ + if (&rseg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); /*Instruction might change stack size, so end block here*/ \ + return op_pc + 1; \ + } ropLseg(DS, cpu_state.seg_ds) ropLseg(ES, cpu_state.seg_es) diff --git a/src/codegen/codegen_ops_shift.h b/src/codegen/codegen_ops_shift.h index 57a828232..d750bfcad 100644 --- a/src/codegen/codegen_ops_shift.h +++ b/src/codegen/codegen_ops_shift.h @@ -1,125 +1,129 @@ -#define SHIFT(size, size2, res_store, immediate) \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - reg = LOAD_REG_ ## size(fetchdat & 7); \ - if (immediate) count = (fetchdat >> 8) & 0x1f; \ - } \ - else \ - { \ - target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - SAVE_EA(); \ - MEM_CHECK_WRITE_ ## size(target_seg); \ - reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \ - if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \ - } \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \ - \ - res_store((uintptr_t)&cpu_state.flags_op1, reg); \ - \ - switch (fetchdat & 0x38) \ - { \ - case 0x20: case 0x30: /*SHL*/ \ - SHL_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \ - break; \ - \ - case 0x28: /*SHR*/ \ - SHR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \ - break; \ - \ - case 0x38: /*SAR*/ \ - SAR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \ - break; \ - } \ - \ - res_store((uintptr_t)&cpu_state.flags_res, reg); \ - if ((fetchdat & 0xc0) == 0xc0) \ - STORE_REG_ ## size ## _RELEASE(reg); \ - else \ - { \ - LOAD_EA(); \ - MEM_STORE_ADDR_EA_ ## size ## _NO_ABRT(target_seg, reg); \ - } +#define SHIFT(size, size2, res_store, immediate) \ + if ((fetchdat & 0xc0) == 0xc0) { \ + reg = LOAD_REG_##size(fetchdat & 7); \ + if (immediate) \ + count = (fetchdat >> 8) & 0x1f; \ + } else { \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + SAVE_EA(); \ + MEM_CHECK_WRITE_##size(target_seg); \ + reg = MEM_LOAD_ADDR_EA_##size##_NO_ABRT(target_seg); \ + if (immediate) \ + count = fastreadb(cs + op_pc + 1) & 0x1f; \ + } \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op2, count); \ + \ + res_store((uintptr_t) &cpu_state.flags_op1, reg); \ + \ + switch (fetchdat & 0x38) { \ + case 0x20: \ + case 0x30: /*SHL*/ \ + SHL_##size##_IMM(reg, count); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHL##size2); \ + break; \ + \ + case 0x28: /*SHR*/ \ + SHR_##size##_IMM(reg, count); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SHR##size2); \ + break; \ + \ + case 0x38: /*SAR*/ \ + SAR_##size##_IMM(reg, count); \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.flags_op, FLAGS_SAR##size2); \ + break; \ + } \ + \ + res_store((uintptr_t) &cpu_state.flags_res, reg); \ + if ((fetchdat & 0xc0) == 0xc0) \ + STORE_REG_##size##_RELEASE(reg); \ + else { \ + LOAD_EA(); \ + MEM_STORE_ADDR_EA_##size##_NO_ABRT(target_seg, reg); \ + } -static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count; - int reg; + x86seg *target_seg = NULL; + int count; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); + SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 1); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count; - int reg; + x86seg *target_seg = NULL; + int count; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); + SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 1); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count; - int reg; + x86seg *target_seg = NULL; + int count; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); + SHIFT(L, 32, STORE_HOST_REG_ADDR, 1); - return op_pc + 2; + return op_pc + 2; } -static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count = 1; - int reg; + x86seg *target_seg = NULL; + int count = 1; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); + SHIFT(B, 8, STORE_HOST_REG_ADDR_BL, 0); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count = 1; - int reg; + x86seg *target_seg = NULL; + int count = 1; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); + SHIFT(W, 16, STORE_HOST_REG_ADDR_WL, 0); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg = NULL; - int count = 1; - int reg; + x86seg *target_seg = NULL; + int count = 1; + int reg; - if ((fetchdat & 0x38) < 0x20) - return 0; + if ((fetchdat & 0x38) < 0x20) + return 0; - SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); + SHIFT(L, 32, STORE_HOST_REG_ADDR, 0); - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_ops_stack.h b/src/codegen/codegen_ops_stack.h index d2fc53aad..265369771 100644 --- a/src/codegen/codegen_ops_stack.h +++ b/src/codegen/codegen_ops_stack.h @@ -1,238 +1,254 @@ -static uint32_t ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_W(opcode & 7); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_W(opcode & 7); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); - return op_pc; + return op_pc; } -static uint32_t ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_L(opcode & 7); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_L(opcode & 7); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); - return op_pc; + return op_pc; } -static uint32_t ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t imm = fetchdat & 0xffff; - int host_reg; + uint16_t imm = fetchdat & 0xffff; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); - return op_pc+2; + return op_pc + 2; } -static uint32_t ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t imm = fastreadl(cs + op_pc); - int host_reg; + uint32_t imm = fastreadl(cs + op_pc); + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); - return op_pc+4; + return op_pc + 4; } -static uint32_t ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_b16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t imm = fetchdat & 0xff; - int host_reg; + uint16_t imm = fetchdat & 0xff; + int host_reg; - if (imm & 0x80) - imm |= 0xff00; + if (imm & 0x80) + imm |= 0xff00; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); - return op_pc+1; + return op_pc + 1; } -static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t imm = fetchdat & 0xff; - int host_reg; + uint32_t imm = fetchdat & 0xff; + int host_reg; - if (imm & 0x80) - imm |= 0xffffff00; + if (imm & 0x80) + imm |= 0xffffff00; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(imm); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(imm); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); - return op_pc+1; + return op_pc + 1; } -static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - SP_MODIFY(2); - STORE_REG_TARGET_W_RELEASE(0, opcode & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + SP_MODIFY(2); + STORE_REG_TARGET_W_RELEASE(0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - SP_MODIFY(4); - STORE_REG_TARGET_L_RELEASE(0, opcode & 7); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + SP_MODIFY(4); + STORE_REG_TARGET_L_RELEASE(0, opcode & 7); - return op_pc; + return op_pc; } -static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(2); - return -1; + return -1; } -static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(4); - return -1; + return -1; } -static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; + uint16_t offset = fetchdat & 0xffff; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(2+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(2 + offset); - return -1; + return -1; } -static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; + uint16_t offset = fetchdat & 0xffff; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.pc, 0); - SP_MODIFY(4+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + STORE_HOST_REG_ADDR((uintptr_t) &cpu_state.pc, 0); + SP_MODIFY(4 + offset); - return -1; + return -1; } -static uint32_t ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCALL_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; - int host_reg; + uint16_t offset = fetchdat & 0xffff; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-2); - host_reg = LOAD_REG_IMM(op_pc+2); - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-2); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-2); + host_reg = LOAD_REG_IMM(op_pc + 2); + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-2); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff); - return -1; + return -1; } -static uint32_t ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropCALL_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fastreadl(cs + op_pc); - int host_reg; + uint32_t offset = fastreadl(cs + op_pc); + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_STACK_TO_EA(-4); - host_reg = LOAD_REG_IMM(op_pc+4); - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); - SP_MODIFY(-4); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_STACK_TO_EA(-4); + host_reg = LOAD_REG_IMM(op_pc + 4); + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); + SP_MODIFY(-4); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset); - return -1; + return -1; } -static uint32_t ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropLEAVE_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); - host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ - ADD_HOST_REG_IMM_W(host_reg, 2); - STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); - STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_EBP_TO_EA(0); + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); + host_reg = LOAD_REG_W(REG_BP); /*SP = BP + 2*/ + ADD_HOST_REG_IMM_W(host_reg, 2); + STORE_REG_TARGET_W_RELEASE(host_reg, REG_SP); + STORE_REG_TARGET_W_RELEASE(0, REG_BP); /*BP = POP_W()*/ - return op_pc; + return op_pc; } -static uint32_t ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropLEAVE_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + int host_reg; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); - LOAD_EBP_TO_EA(0); - MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); - host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ - ADD_HOST_REG_IMM(host_reg, 4); - STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); - STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); + LOAD_EBP_TO_EA(0); + MEM_LOAD_ADDR_EA_L(&cpu_state.seg_ss); + host_reg = LOAD_REG_L(REG_EBP); /*ESP = EBP + 4*/ + ADD_HOST_REG_IMM(host_reg, 4); + STORE_REG_TARGET_L_RELEASE(host_reg, REG_ESP); + STORE_REG_TARGET_L_RELEASE(0, REG_EBP); /*EBP = POP_L()*/ - return op_pc; + return op_pc; } -#define ROP_PUSH_SEG(seg) \ -static uint32_t ropPUSH_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-2); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPUSH_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - int host_reg; \ - \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(-4); \ - host_reg = LOAD_VAR_W((uintptr_t)&seg); \ - MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ - SP_MODIFY(-4); \ - \ - return op_pc; \ -} +#define ROP_PUSH_SEG(seg) \ + static uint32_t ropPUSH_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-2); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_W(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-2); \ + \ + return op_pc; \ + } \ + static uint32_t ropPUSH_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int host_reg; \ + \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(-4); \ + host_reg = LOAD_VAR_W((uintptr_t) &seg); \ + MEM_STORE_ADDR_EA_L(&cpu_state.seg_ss, host_reg); \ + SP_MODIFY(-4); \ + \ + return op_pc; \ + } ROP_PUSH_SEG(CS) ROP_PUSH_SEG(DS) @@ -241,27 +257,27 @@ ROP_PUSH_SEG(FS) ROP_PUSH_SEG(GS) ROP_PUSH_SEG(SS) -#define ROP_POP_SEG(seg, rseg) \ -static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(2); \ - \ - return op_pc; \ -} \ -static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ -{ \ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ - LOAD_STACK_TO_EA(0); \ - MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ - LOAD_SEG(0, &rseg); \ - SP_MODIFY(4); \ - \ - return op_pc; \ -} +#define ROP_POP_SEG(seg, rseg) \ + static uint32_t ropPOP_##seg##_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(2); \ + \ + return op_pc; \ + } \ + static uint32_t ropPOP_##seg##_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.oldpc, op_old_pc); \ + LOAD_STACK_TO_EA(0); \ + MEM_LOAD_ADDR_EA_W(&cpu_state.seg_ss); \ + LOAD_SEG(0, &rseg); \ + SP_MODIFY(4); \ + \ + return op_pc; \ + } ROP_POP_SEG(DS, cpu_state.seg_ds) ROP_POP_SEG(ES, cpu_state.seg_es) diff --git a/src/codegen/codegen_ops_x86-64.h b/src/codegen/codegen_ops_x86-64.h index 67c24c99c..00518d9ba 100644 --- a/src/codegen/codegen_ops_x86-64.h +++ b/src/codegen/codegen_ops_x86-64.h @@ -4,4519 +4,4148 @@ #include #define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 +#define HOST_REG_XMM_END 7 -#define IS_32_ADDR(x) !(((uintptr_t)x) & 0xffffffff00000000) +#define IS_32_ADDR(x) !(((uintptr_t) x) & 0xffffffff00000000) -static __inline int find_host_xmm_reg(void) +static __inline int +find_host_xmm_reg(void) { - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } + int c; + for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) { + if (host_reg_xmm_mapping[c] == -1) + break; + } - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; + if (c == HOST_REG_XMM_END) + fatal("Out of host XMM regs!\n"); + return c; } -static __inline void call(codeblock_t *block, uintptr_t func) +static __inline void +call(codeblock_t *block, uintptr_t func) { - intptr_t diff = (intptr_t)(func - (uintptr_t)&block->data[block_pos + 5]); + intptr_t diff = (intptr_t) (func - (uintptr_t) &block->data[block_pos + 5]); - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; + codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - if (diff >= -0x80000000LL && diff < 0x7fffffffLL) - { - addbyte(0xE8); /*CALL*/ - addlong((uint32_t)diff); - } - else - { - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); - } + if (diff >= -0x80000000LL && diff < 0x7fffffffLL) { + addbyte(0xE8); /*CALL*/ + addlong((uint32_t) diff); + } else { + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); + } } -static __inline void call_long(uintptr_t func) +static __inline void +call_long(uintptr_t func) { - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; + codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); } -static __inline void load_param_1_32(codeblock_t *block, uint32_t param) +static __inline void +load_param_1_32(codeblock_t *block, uint32_t param) { #if _WIN64 - addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ + addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ #else - addbyte(0xbf); /*MOVL $fetchdat,%edi*/ + addbyte(0xbf); /*MOVL $fetchdat,%edi*/ #endif - addlong(param); + addlong(param); } -static __inline void load_param_1_reg_32(int reg) +static __inline void +load_param_1_reg_32(int reg) { #if _WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc0 | REG_ECX | (reg << 3)); + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc0 | REG_ECX | (reg << 3)); #else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDI, EAX*/ - addbyte(0xc0 | REG_EDI | (reg << 3)); + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV EDI, EAX*/ + addbyte(0xc0 | REG_EDI | (reg << 3)); #endif } #if 0 static __inline void load_param_1_64(codeblock_t *block, uint64_t param) { addbyte(0x48); -#if _WIN64 +# if _WIN64 addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ -#else +# else addbyte(0xbf); /*MOVL $fetchdat,%edi*/ -#endif +# endif addquad(param); } #endif -static __inline void load_param_2_32(codeblock_t *block, uint32_t param) +static __inline void +load_param_2_32(codeblock_t *block, uint32_t param) { #if _WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ + addbyte(0xba); /*MOVL $fetchdat,%edx*/ #else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ + addbyte(0xbe); /*MOVL $fetchdat,%esi*/ #endif - addlong(param); + addlong(param); } -static __inline void load_param_2_reg_32(int reg) +static __inline void +load_param_2_reg_32(int reg) { #if _WIN64 - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV EDX, EAX*/ + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV EDX, EAX*/ + addbyte(0xc0 | REG_EDX | (reg << 3)); +#else + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV ESI, EAX*/ + addbyte(0xc0 | REG_ESI | (reg << 3)); +#endif +} +static __inline void +load_param_2_64(codeblock_t *block, uint64_t param) +{ + addbyte(0x48); +#if _WIN64 + addbyte(0xba); /*MOVL $fetchdat,%edx*/ +#else + addbyte(0xbe); /*MOVL $fetchdat,%esi*/ +#endif + addquad(param); +} +static __inline void +load_param_2_reg_64(int reg) +{ + if (reg & 8) { +#if _WIN64 + addbyte(0x4c); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); +#else + addbyte(0x4c); /*MOVL ESI,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); +#endif + } else { +#if _WIN64 + addbyte(0x48); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); +#else + addbyte(0x48); /*MOVL ESI,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); +#endif + } +} + +static __inline void +load_param_3_reg_32(int reg) +{ + if (reg & 8) { +#if _WIN64 + addbyte(0x45); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); +#else + addbyte(0x44); /*MOV EDX, reg*/ + addbyte(0x89); addbyte(0xc0 | REG_EDX | (reg << 3)); -#else - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV ESI, EAX*/ - addbyte(0xc0 | REG_ESI | (reg << 3)); #endif -} -static __inline void load_param_2_64(codeblock_t *block, uint64_t param) -{ - addbyte(0x48); + } else { #if _WIN64 - addbyte(0xba); /*MOVL $fetchdat,%edx*/ + addbyte(0x41); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); #else - addbyte(0xbe); /*MOVL $fetchdat,%esi*/ + addbyte(0x90); + addbyte(0x89); /*MOV EDX, reg*/ + addbyte(0xc0 | REG_EDX | (reg << 3)); #endif - addquad(param); + } } -static __inline void load_param_2_reg_64(int reg) +static __inline void +load_param_3_reg_64(int reg) { - if (reg & 8) - { + if (reg & 8) { #if _WIN64 - addbyte(0x4c); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); + addbyte(0x4d); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); #else - addbyte(0x4c); /*MOVL ESI,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); + addbyte(0x4c); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); #endif - } - else - { + } else { #if _WIN64 - addbyte(0x48); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); + addbyte(0x49); /*MOVL R8,reg*/ + addbyte(0x89); + addbyte(0xc0 | ((reg & 7) << 3)); #else - addbyte(0x48); /*MOVL ESI,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_ESI | ((reg & 7) << 3)); + addbyte(0x48); /*MOVL EDX,reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); #endif + } +} + +static __inline void +CALL_FUNC(uintptr_t func) +{ + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; + codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + + addbyte(0x48); /*MOV RAX, func*/ + addbyte(0xb8); + addquad(func); + addbyte(0xff); /*CALL RAX*/ + addbyte(0xd0); +} + +static __inline void +RELEASE_REG(int host_reg) +{ +} + +static __inline int +LOAD_REG_B(int reg) +{ + int host_reg = reg & 3; + + if (!codegen_reg_loaded[reg & 3]) { + addbyte(0x44); /*MOVZX W[reg],host_reg*/ + addbyte(0x8b); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[host_reg & 3].b)); + } + + codegen_reg_loaded[reg & 3] = 1; + + if (reg & 4) + return host_reg | 0x18; + + return host_reg | 8; +} +static __inline int +LOAD_REG_W(int reg) +{ + int host_reg = reg; + + if (!codegen_reg_loaded[reg & 7]) { + addbyte(0x44); /*MOVZX W[reg],host_reg*/ + addbyte(0x8b); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].w)); + } + + codegen_reg_loaded[reg & 7] = 1; + + return host_reg | 8; +} +static __inline int +LOAD_REG_L(int reg) +{ + int host_reg = reg; + + if (!codegen_reg_loaded[reg & 7]) { + addbyte(0x44); /*MOVZX W[reg],host_reg*/ + addbyte(0x8b); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].l)); + } + + codegen_reg_loaded[reg & 7] = 1; + + return host_reg | 8; +} + +static __inline int +LOAD_REG_IMM(uint32_t imm) +{ + int host_reg = REG_EBX; + + addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ + addlong(imm); + + return host_reg; +} + +static __inline void +STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) +{ + int dest_reg = LOAD_REG_L(guest_reg & 3) & 7; + + if (guest_reg & 4) { + if (host_reg & 8) { + addbyte(0x66); /*MOV AX, host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 3) << 3)); + } else if (host_reg & 3) { + addbyte(0x66); /*MOV AX, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 3) << 3)); } -} - -static __inline void load_param_3_reg_32(int reg) -{ - if (reg & 8) - { -#if _WIN64 - addbyte(0x45); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x44); /*MOV EDX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif + if (host_reg & 0x10) { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } else { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(0x08); } - else - { -#if _WIN64 - addbyte(0x41); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x90); - addbyte(0x89); /*MOV EDX, reg*/ - addbyte(0xc0 | REG_EDX | (reg << 3)); -#endif - } -} -static __inline void load_param_3_reg_64(int reg) -{ - if (reg & 8) - { -#if _WIN64 - addbyte(0x4d); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x4c); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } - else - { -#if _WIN64 - addbyte(0x49); /*MOVL R8,reg*/ - addbyte(0x89); - addbyte(0xc0 | ((reg & 7) << 3)); -#else - addbyte(0x48); /*MOVL EDX,reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((reg & 7) << 3)); -#endif - } -} - -static __inline void CALL_FUNC(uintptr_t func) -{ - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - addbyte(0x48); /*MOV RAX, func*/ - addbyte(0xb8); - addquad(func); - addbyte(0xff); /*CALL RAX*/ - addbyte(0xd0); -} - -static __inline void RELEASE_REG(int host_reg) -{ -} - -static __inline int LOAD_REG_B(int reg) -{ - int host_reg = reg & 3; - - if (!codegen_reg_loaded[reg & 3]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[host_reg & 3].b)); - } - - codegen_reg_loaded[reg & 3] = 1; - - if (reg & 4) - return host_reg | 0x18; - - return host_reg | 8; -} -static __inline int LOAD_REG_W(int reg) -{ - int host_reg = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} -static __inline int LOAD_REG_L(int reg) -{ - int host_reg = reg; - - if (!codegen_reg_loaded[reg & 7]) - { - addbyte(0x44); /*MOVZX W[reg],host_reg*/ - addbyte(0x8b); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); - } - - codegen_reg_loaded[reg & 7] = 1; - - return host_reg | 8; -} - -static __inline int LOAD_REG_IMM(uint32_t imm) -{ - int host_reg = REG_EBX; - - addbyte(0xb8 | REG_EBX); /*MOVL EBX, imm*/ - addlong(imm); - - return host_reg; -} - -static __inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 3) & 7; - - if (guest_reg & 4) - { - if (host_reg & 8) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - } - else if (host_reg & 3) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - } - if (host_reg & 0x10) - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - else - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(0x08); - } - addbyte(0x66); /*AND dest_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | dest_reg); - addword(0x00ff); - addbyte(0x66); /*OR dest_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | dest_reg); - addbyte(0x66); /*MOVW regs[guest_reg].w, dest_reg*/ + addbyte(0x66); /*AND dest_reg, 0x00ff*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xe0 | dest_reg); + addword(0x00ff); + addbyte(0x66); /*OR dest_reg, AX*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | dest_reg); + addbyte(0x66); /*MOVW regs[guest_reg].w, dest_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | (dest_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 3].w)); + } else { + if (host_reg & 8) { + if (host_reg & 0x10) { + addbyte(0x66); /*MOV AX, host_reg*/ addbyte(0x44); addbyte(0x89); - addbyte(0x45 | (dest_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].w)); - } - else - { - if (host_reg & 8) - { - if (host_reg & 0x10) - { - addbyte(0x66); /*MOV AX, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 3) << 3)); - addbyte(0x88); /*MOV AL, AH*/ - addbyte(0xe0); - addbyte(0x41); /*MOV dest_reg, AL*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7)); - addbyte(0x88); /*MOVB regs[reg].b, AH*/ - addbyte(0x65); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - else - { - addbyte(0x45); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x44); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x88); - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } - else - { - if (host_reg & 0x10) - { - addbyte(0xc1); /*SHR host_reg, 8*/ - addbyte(0xe8 | (host_reg & 7)); - addbyte(8); - } - addbyte(0x41); /*MOVB dest_reg, host_reg*/ - addbyte(0x88); - addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); - addbyte(0x88); /*MOVB regs[guest_reg].b, host_reg*/ - addbyte(0x45 | ((host_reg & 3) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 3].b)); - } - } -} -static __inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; - - if (host_reg & 8) - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x45); - addbyte(0x89); - addbyte(0xc0 | dest_reg | ((host_reg & 7) << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } - else - { - addbyte(0x66); /*MOVW guest_reg, host_reg*/ - addbyte(0x41); - addbyte(0x89); - addbyte(0xc0 | dest_reg | (host_reg << 3)); - addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); - } -} -static __inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x44); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } - else - { - addbyte(0x41); /*MOVL guest_reg, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | guest_reg | (host_reg << 3)); - addbyte(0x89); /*MOVL regs[guest_reg].l, host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); - } -} - -static __inline void STORE_REG_B_RELEASE(int host_reg) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*MOVW [reg],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].w)); - } - else - { - addbyte(0x44); /*MOVB [reg],host_reg*/ + addbyte(0xc0 | ((host_reg & 3) << 3)); + addbyte(0x88); /*MOV AL, AH*/ + addbyte(0xe0); + addbyte(0x41); /*MOV dest_reg, AL*/ addbyte(0x88); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].b)); + addbyte(0xc0 | (dest_reg & 7)); + addbyte(0x88); /*MOVB regs[reg].b, AH*/ + addbyte(0x65); + addbyte(cpu_state_offset(regs[guest_reg & 3].b)); + } else { + addbyte(0x45); /*MOVB dest_reg, host_reg*/ + addbyte(0x88); + addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); + addbyte(0x44); /*MOVB regs[guest_reg].b, host_reg*/ + addbyte(0x88); + addbyte(0x45 | ((host_reg & 3) << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 3].b)); + } + } else { + if (host_reg & 0x10) { + addbyte(0xc1); /*SHR host_reg, 8*/ + addbyte(0xe8 | (host_reg & 7)); + addbyte(8); + } + addbyte(0x41); /*MOVB dest_reg, host_reg*/ + addbyte(0x88); + addbyte(0xc0 | (dest_reg & 7) | ((host_reg & 7) << 3)); + addbyte(0x88); /*MOVB regs[guest_reg].b, host_reg*/ + addbyte(0x45 | ((host_reg & 3) << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 3].b)); } + } } -static __inline void STORE_REG_W_RELEASE(int host_reg) +static __inline void +STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) { + int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; + + if (host_reg & 8) { + addbyte(0x66); /*MOVW guest_reg, host_reg*/ + addbyte(0x45); + addbyte(0x89); + addbyte(0xc0 | dest_reg | ((host_reg & 7) << 3)); + addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].w)); + } else { + addbyte(0x66); /*MOVW guest_reg, host_reg*/ + addbyte(0x41); + addbyte(0x89); + addbyte(0xc0 | dest_reg | (host_reg << 3)); + addbyte(0x66); /*MOVW regs[guest_reg].w, host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].w)); + } +} +static __inline void +STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) +{ + if (host_reg & 8) { + addbyte(0x45); /*MOVL guest_reg, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | guest_reg | (host_reg << 3)); + addbyte(0x44); /*MOVL regs[guest_reg].l, host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].l)); + } else { + addbyte(0x41); /*MOVL guest_reg, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | guest_reg | (host_reg << 3)); + addbyte(0x89); /*MOVL regs[guest_reg].l, host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[guest_reg & 7].l)); + } +} + +static __inline void +STORE_REG_B_RELEASE(int host_reg) +{ + if (host_reg & 0x10) { addbyte(0x66); /*MOVW [reg],host_reg*/ addbyte(0x44); addbyte(0x89); addbyte(0x45 | ((host_reg & 7) << 3)); addbyte(cpu_state_offset(regs[host_reg & 7].w)); -} -static __inline void STORE_REG_L_RELEASE(int host_reg) -{ - addbyte(0x44); /*MOVL [reg],host_reg*/ - addbyte(0x89); + } else { + addbyte(0x44); /*MOVB [reg],host_reg*/ + addbyte(0x88); addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte(cpu_state_offset(regs[host_reg & 7].l)); + addbyte(cpu_state_offset(regs[host_reg & 7].b)); + } +} +static __inline void +STORE_REG_W_RELEASE(int host_reg) +{ + addbyte(0x66); /*MOVW [reg],host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte(cpu_state_offset(regs[host_reg & 7].w)); +} +static __inline void +STORE_REG_L_RELEASE(int host_reg) +{ + addbyte(0x44); /*MOVL [reg],host_reg*/ + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte(cpu_state_offset(regs[host_reg & 7].l)); } -static __inline void STORE_IMM_REG_B(int reg, uint8_t val) +static __inline void +STORE_IMM_REG_B(int reg, uint8_t val) { - if (reg & 4) - { - int host_reg = LOAD_REG_W(reg & 3) & 7; - addbyte(0x66); /*AND host_reg, 0x00ff*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | host_reg); - addword(0x00ff); - addbyte(0x66); /*OR host_reg, val << 8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | host_reg); - addword(val << 8); - addbyte(0x66); /*MOVW host_reg, regs[host_reg].w*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 3].w)); - } - else - { - addbyte(0x41); /*MOVB reg, imm*/ - addbyte(0xb0 | reg); - addbyte(val); - addbyte(0x44); /*MOVB reg, regs[reg].b*/ - addbyte(0x88); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].b)); - } -} -static __inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW reg, imm*/ + if (reg & 4) { + int host_reg = LOAD_REG_W(reg & 3) & 7; + addbyte(0x66); /*AND host_reg, 0x00ff*/ addbyte(0x41); - addbyte(0xb8 | reg); - addword(val); - addbyte(0x66); /*MOVW reg, regs[reg].w*/ + addbyte(0x81); + addbyte(0xe0 | host_reg); + addword(0x00ff); + addbyte(0x66); /*OR host_reg, val << 8*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xc8 | host_reg); + addword(val << 8); + addbyte(0x66); /*MOVW host_reg, regs[host_reg].w*/ addbyte(0x44); addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte(cpu_state_offset(regs[reg & 3].w)); + } else { + addbyte(0x41); /*MOVB reg, imm*/ + addbyte(0xb0 | reg); + addbyte(val); + addbyte(0x44); /*MOVB reg, regs[reg].b*/ + addbyte(0x88); addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); + addbyte(cpu_state_offset(regs[reg & 7].b)); + } } -static __inline void STORE_IMM_REG_L(int reg, uint32_t val) +static __inline void +STORE_IMM_REG_W(int reg, uint16_t val) { - addbyte(0x41); /*MOVL reg, imm*/ - addbyte(0xb8 | reg); + addbyte(0x66); /*MOVW reg, imm*/ + addbyte(0x41); + addbyte(0xb8 | reg); + addword(val); + addbyte(0x66); /*MOVW reg, regs[reg].w*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | (reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].w)); +} +static __inline void +STORE_IMM_REG_L(int reg, uint32_t val) +{ + addbyte(0x41); /*MOVL reg, imm*/ + addbyte(0xb8 | reg); + addlong(val); + addbyte(0x44); /*MOVL reg, regs[reg].l*/ + addbyte(0x89); + addbyte(0x45 | (reg << 3)); + addbyte(cpu_state_offset(regs[reg & 7].l)); +} + +static __inline void +STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x45); + addbyte(addr - (uintptr_t) &cpu_state - 128); addlong(val); - addbyte(0x44); /*MOVL reg, regs[reg].l*/ - addbyte(0x89); - addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); + } else if (addr < 0x100000000) { + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x04); + addbyte(0x25); + addlong(addr); + addlong(val); + } else { + addbyte(0x48); /*MOV ESI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad(addr); + addbyte(0xc7); /*MOVL [ESI], val*/ + addbyte(0x00 | REG_ESI); + addlong(val); + } } -static __inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) +static x86seg * +FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uintptr_t)&cpu_state - 128); - addlong(val); + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; + + if (!mod && rm == 6) { + addbyte(0xb8); /*MOVL EAX, imm*/ + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + int base_reg = 0, index_reg = 0; + + switch (rm) { + case 0: + case 1: + case 7: + base_reg = LOAD_REG_W(REG_BX); + break; + case 2: + case 3: + case 6: + base_reg = LOAD_REG_W(REG_BP); + break; + case 4: + base_reg = LOAD_REG_W(REG_SI); + break; + case 5: + base_reg = LOAD_REG_W(REG_DI); + break; } - else if (addr < 0x100000000) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x04); - addbyte(0x25); - addlong(addr); - addlong(val); + if (!(rm & 4)) { + if (rm & 1) + index_reg = LOAD_REG_W(REG_DI); + else + index_reg = LOAD_REG_W(REG_SI); } - else - { - addbyte(0x48); /*MOV ESI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad(addr); - addbyte(0xc7); /*MOVL [ESI], val*/ - addbyte(0x00 | REG_ESI); - addlong(val); - } -} + base_reg &= 7; + index_reg &= 7; - - - -static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - - if (!mod && rm == 6) - { - addbyte(0xb8); /*MOVL EAX, imm*/ - addlong((fetchdat >> 8) & 0xffff); - (*op_pc) += 2; - } - else - { - int base_reg = 0, index_reg = 0; - - switch (rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; + switch (mod) { + case 0: + if (rm & 4) { + addbyte(0x41); /*MOVZX EAX, base_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xc0 | base_reg); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3)); + } } - if (!(rm & 4)) - { - if (rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); + break; + case 1: + if (rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte((fetchdat >> 8) & 0xff); } - base_reg &= 7; - index_reg &= 7; - - switch (mod) - { - case 0: - if (rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (mod || !(rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; -} -static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - uint32_t new_eaaddr; - - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; - (*op_pc)++; - - if (mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } + break; + case 2: + if (rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong((fetchdat >> 8) & 0xffff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3)); + addlong((fetchdat >> 8) & 0xffff); } - else - { - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; + (*op_pc) += 2; + break; + } + if (mod || !(rm & 4)) { + addbyte(0x25); /*ANDL $0xffff, %eax*/ + addlong(0xffff); } - else - { - int base_reg; - if (!mod && rm == 5) - { + if (mod1seg[rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; +} +static x86seg * +FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +{ + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; + uint32_t new_eaaddr; + + if (rm == 4) { + uint8_t sib = fetchdat >> 8; + int base_reg = -1, index_reg = -1; + + (*op_pc)++; + + if (mod || (sib & 7) != 5) + base_reg = LOAD_REG_L(sib & 7) & 7; + + if (((sib >> 3) & 7) != 4) + index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; + + if (index_reg == -1) { + switch (mod) { + case 0: + if ((sib & 7) == 5) { new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ + addbyte(0xb8); /*MOV EAX, imm32*/ addlong(new_eaaddr); (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(rm) & 7; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - else - { + } else { addbyte(0x44); /*MOV EAX, base_reg*/ addbyte(0x89); addbyte(0xc0 | (base_reg << 3)); - } + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x44); + addbyte(0x24); + } else { + addbyte(0x40 | base_reg); + } + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x84); + addbyte(0x24); + } else { + addbyte(0x80 | base_reg); + } + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } + } else { + switch (mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + if (sib >> 6) { + addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ + addbyte(0x42); + addbyte(0x8d); + addbyte(0x04); + addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); + addlong(new_eaaddr); + } else { + addbyte(0x67); /*LEA EAX, imm32+index_reg*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | index_reg); + addlong(new_eaaddr); + } + (*op_pc) += 4; + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + } + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } } - return op_ea_seg; + if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ + { + addbyte(0x05); + addlong(stack_offset); + } + if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } else { + int base_reg; + + if (!mod && rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + base_reg = LOAD_REG_L(rm) & 7; + if (mod) { + if (rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (mod == 1) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, base_reg+imm32*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong(new_eaaddr); + (*op_pc) += 4; + } + } else { + addbyte(0x44); /*MOV EAX, base_reg*/ + addbyte(0x89); + addbyte(0xc0 | (base_reg << 3)); + } + } + return op_ea_seg; } -static __inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +static __inline x86seg * +FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) { - if (op_32 & 0x200) - return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); + if (op_32 & 0x200) + return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); + return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); } - - -static __inline void CHECK_SEG_READ(x86seg *seg) +static __inline void +CHECK_SEG_READ(x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static __inline void CHECK_SEG_WRITE(x86seg *seg) -{ - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x83); /*CMP RSI, -1*/ - addbyte(0xe8 | REG_ESI); - addbyte(0xff); - } - addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ - addbyte(0x84); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - - seg->checked = 1; -} -static __inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; - - if (IS_32_ADDR(&seg->base)) - { - addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ - addlong((uint32_t)(uintptr_t)seg); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)seg); - } - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_low - (uintptr_t)seg); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x46); - addbyte((uintptr_t)&seg->limit_high - (uintptr_t)seg); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static __inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); + if (IS_32_ADDR(&seg->base)) { + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmembl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static __inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x83); /*CMP RSI, -1*/ addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ - addbyte(0x8b); - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xff); + } + addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ + addbyte(0x84); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + + seg->checked = 1; } -static __inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +static __inline void +CHECK_SEG_WRITE(x86seg *seg) { - addbyte(0x83); /*ADD EAX, offset*/ + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; + + if (IS_32_ADDR(&seg->base)) { + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + addbyte(-1); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x83); /*CMP RSI, -1*/ + addbyte(0xe8 | REG_ESI); + addbyte(0xff); + } + addbyte(0x0f); /*JE GPF_BLOCK_OFFSET*/ + addbyte(0x84); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + + seg->checked = 1; +} +static __inline void +CHECK_SEG_LIMITS(x86seg *seg, int end_offset) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; + + if (IS_32_ADDR(&seg->base)) { + addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ + addlong((uint32_t) (uintptr_t) seg); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) seg); + } + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ + addbyte(0x46); + addbyte((uintptr_t) &seg->limit_low - (uintptr_t) seg); + addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ + addbyte(0x82); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + if (end_offset) { + addbyte(0x83); /*ADD EAX, end_offset*/ addbyte(0xc0); - addbyte(offset); - MEM_LOAD_ADDR_EA_W(seg); + addbyte(end_offset); + addbyte(0x3b); /*CMP EAX, seg->limit_high*/ + addbyte(0x46); + addbyte((uintptr_t) &seg->limit_high - (uintptr_t) seg); + addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ + addbyte(0x87); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*SUB EAX, end_offset*/ + addbyte(0xe8); + addbyte(end_offset); + } } -static __inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) + +static __inline void +MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static __inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); addbyte(0x8b); - addbyte(0x04); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmembl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_LOAD_ADDR_EA_W(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ + addbyte(0x8b); + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemwl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +{ + addbyte(0x83); /*ADD EAX, offset*/ + addbyte(0xc0); + addbyte(offset); + MEM_LOAD_ADDR_EA_W(seg); +} +static __inline void +MEM_LOAD_ADDR_EA_L(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemll); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_LOAD_ADDR_EA_Q(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ + addbyte(0x8b); + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemql); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} + +static __inline void +MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_B(seg); +} +static __inline void +MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_W(seg); +} +static __inline void +MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_L(seg); +} + +static __inline void +MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) +{ + if (host_reg & 0x10) { + /*Handle high byte of register*/ + if (host_reg & 8) { + addbyte(0x45); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } else { + addbyte(0x41); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } + addbyte(0x66); /*SHR R8, 8*/ + addbyte(0x41); + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + host_reg = 8; + } + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x88); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + } else { + addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12 + 4 + 6); + } else { + addbyte(2 + 2 + 2 + 12 + 4 + 6); + } + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_32(host_reg); + call_long((uintptr_t) writemembl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ } - -static __inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +static __inline void +MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_B(seg); -} -static __inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_W(seg); -} -static __inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_L(seg); -} - -static __inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) -{ - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12+4+6); - } else { - addbyte(2+2+2+12+4+6); - } - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(host_reg); - call_long((uintptr_t)writemembl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static __inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12+4+6); - } else { - addbyte(2+2+2+12+4+6); - } - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(host_reg); - call_long((uintptr_t)writememwl); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 5 : 4) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 5 : 4) + 2); + if (host_reg & 8) { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12 + 4 + 6); + } else { + addbyte(2 + 2 + 2 + 12 + 4 + 6); + } + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_32(host_reg); + call_long((uintptr_t) writememwl); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ } -static __inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 4:3)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12+4+6); - } else { - addbyte(2+2+2+12+4+6); - } - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_32(host_reg); - call_long((uintptr_t)writememll); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} -static __inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 7*/ - addbyte(0xc7); - addlong(7); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 4 : 3) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12 + 4 + 6); + } else { + addbyte(2 + 2 + 2 + 12 + 4 + 6); + } + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_32(host_reg); + call_long((uintptr_t) writememll); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} +static __inline void +MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + if (host_reg & 8) { + addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 3 + 12 + 4 + 6); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + load_param_2_reg_64(host_reg); + call_long((uintptr_t) writememql); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} + +static __inline void +MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_B(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_W(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_L(seg, host_reg); +} + +static __inline void +STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) +{ + int temp_reg = REG_ECX; + + if (host_reg_mapping[REG_ECX] != -1) + temp_reg = REG_EBX; + + if (host_reg & 0x10) { if (host_reg & 8) - { - addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+3+12+4+6); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - load_param_2_reg_64(host_reg); - call_long((uintptr_t)writememql); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - /*done:*/ -} - -static __inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_B(seg, host_reg); -} -static __inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_W(seg, host_reg); -} -static __inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_L(seg, host_reg); -} - -static __inline void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 0x10) - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb7); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - addbyte(0xc1); /*SHR temp_reg, 8*/ - addbyte(0xe8 | temp_reg); - addbyte(8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ - addbyte(0xb6); - addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - } - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static __inline void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) -{ - int temp_reg = REG_ECX; - - if (host_reg_mapping[REG_ECX] != -1) - temp_reg = REG_EBX; - - if (host_reg & 8) - addbyte(0x41); + addbyte(0x41); addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ addbyte(0xb7); addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x89); /*MOV addr, temp_reg*/ - addbyte(0x04 | (temp_reg << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - addbyte(0x89); /*MOV [RSI], temp_reg*/ - addbyte(0x06 | (temp_reg << 3)); - } -} -static __inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - addbyte(0x66); - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVW [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} -static __inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL addr,host_reg*/ - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(0x25); - addlong(addr); - } - else - { - addbyte(0x48); /*MOV RSI, addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)addr); - - if (host_reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [RSI],host_reg*/ - addbyte(0x06 | ((host_reg & 7) << 3)); - } -} - -static __inline void AND_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - addbyte(0x66); /*OR AX, 0x00ff*/ - addbyte(0x0d); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ANDB dst_reg, AL*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*OR src_reg, 0xff*/ - addbyte(0x81); - addbyte(0xc8 | src_reg); - addword(0xff); - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ANDB dst_reg, src_reg*/ - addbyte(0x20); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x20); /*ANDB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x20); /*ANDB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } -} -static __inline void AND_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ANDW dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static __inline void AND_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ANDL dst_reg, src_reg*/ - addbyte(0x21); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } -} -static __inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } -} - -static __inline int TEST_HOST_REG_B(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; - } - - AND_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; -} -static __inline int TEST_HOST_REG_W(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; -} -static __inline int TEST_HOST_REG_L(int dst_reg, int src_reg) -{ - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - AND_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; -} -static __inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) -{ + addbyte(0xc1); /*SHR temp_reg, 8*/ + addbyte(0xe8 | temp_reg); + addbyte(8); + } else { if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EDX | ((host_reg & 7) << 3)); - host_reg = REG_EDX | (host_reg & 0x10); - } - if (host_reg & 0x10) - { - addbyte(0x66); /*ANDW host_reg, imm<<8*/ - addbyte(0x81); - addbyte(0xe0 | (host_reg & 7)); - addword((imm << 8) | 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xe0 | (host_reg & 7)); - addlong(imm); - } + addbyte(0x41); + addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ + addbyte(0xb6); + addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); + } + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x45 | (temp_reg << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x04 | (temp_reg << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + addbyte(0x89); /*MOV [RSI], temp_reg*/ + addbyte(0x06 | (temp_reg << 3)); + } +} +static __inline void +STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) +{ + int temp_reg = REG_ECX; - return host_reg; + if (host_reg_mapping[REG_ECX] != -1) + temp_reg = REG_EBX; + + if (host_reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX temp_reg, host_reg*/ + addbyte(0xb7); + addbyte(0xc0 | (temp_reg << 3) | (host_reg & 7)); + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x45 | (temp_reg << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x89); /*MOV addr, temp_reg*/ + addbyte(0x04 | (temp_reg << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + addbyte(0x89); /*MOV [RSI], temp_reg*/ + addbyte(0x06 | (temp_reg << 3)); + } +} +static __inline void +STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x66); /*MOVW [addr],host_reg*/ + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x66); + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVW addr,host_reg*/ + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + + addbyte(0x66); + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVW [RSI],host_reg*/ + addbyte(0x06 | ((host_reg & 7) << 3)); + } +} +static __inline void +STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVL [addr],host_reg*/ + addbyte(0x45 | ((host_reg & 7) << 3)); + addbyte((uint32_t) addr - (uint32_t) (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVL addr,host_reg*/ + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(0x25); + addlong(addr); + } else { + addbyte(0x48); /*MOV RSI, addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) addr); + + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOVL [RSI],host_reg*/ + addbyte(0x06 | ((host_reg & 7) << 3)); + } } -static __inline void OR_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ORB dst_reg, AL*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } + addbyte(0x66); /*OR AX, 0x00ff*/ + addbyte(0x0d); + addword(0xff); + addbyte(0x66); /*ANDW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*ANDB dst_reg, AL*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*ANDB dst_reg, src_reg*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*OR src_reg, 0xff*/ + addbyte(0x81); + addbyte(0xc8 | src_reg); + addword(0xff); + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*ANDB dst_reg, src_reg*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ORB dst_reg, src_reg*/ - addbyte(0x08); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x08); /*ORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x08); /*ORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x20); /*ANDB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*ANDB dst_reg, src_reg*/ + addbyte(0x20); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x20); /*ANDB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x20); /*ANDB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static __inline void OR_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*ORW dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*ANDW dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static __inline void OR_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ORL dst_reg, src_reg*/ - addbyte(0x09); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x09); /*ORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*ANDL dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*ANDL dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*ANDL dst_reg, src_reg*/ + addbyte(0x21); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x21); /*ANDL dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static __inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +AND_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xc8 | (host_reg & 7)); - addlong(imm); - } + if (host_reg & 0x10) { + addbyte(0x66); /*ANDW host_reg, imm<<8*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); + addbyte(0xe0 | (host_reg & 7)); + addword((imm << 8) | 0xff); + } else { + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); /*ANDL host_reg, imm*/ + addbyte(0xe0 | (host_reg & 7)); + addlong(imm); + } } -static __inline void XOR_HOST_REG_B(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*XORW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*XORB dst_reg, AL*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*XORB dst_reg, src_reg*/ - addbyte(0x30); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x30); /*XORB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x30); /*XORB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - } + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = (dst_reg & 0x10) | REG_EDX; + } + + AND_HOST_REG_B(dst_reg, src_reg); + + return dst_reg & ~0x10; } -static __inline void XOR_HOST_REG_W(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + AND_HOST_REG_W(dst_reg, src_reg); + + return dst_reg; } -static __inline void XOR_HOST_REG_L(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*XORL dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*XORW dst_reg, src_reg*/ - addbyte(0x31); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x31); /*XORW dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + AND_HOST_REG_L(dst_reg, src_reg); + + return dst_reg; } -static __inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline int +TEST_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (host_reg & 0x10) - { - addbyte(0x66); /*ORW host_reg, imm<<8*/ - addbyte(0x41); - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addword(imm << 8); - } - else if (host_reg & 8) - { - addbyte(0x41); /*ORL host_reg, imm*/ - addbyte(0x81); - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xf0 | (host_reg & 7)); - addlong(imm); - } + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EDX | ((host_reg & 7) << 3)); + host_reg = REG_EDX | (host_reg & 0x10); + } + if (host_reg & 0x10) { + addbyte(0x66); /*ANDW host_reg, imm<<8*/ + addbyte(0x81); + addbyte(0xe0 | (host_reg & 7)); + addword((imm << 8) | 0xff); + } else { + addbyte(0x81); /*ANDL host_reg, imm*/ + addbyte(0xe0 | (host_reg & 7)); + addlong(imm); + } + + return host_reg; } -static __inline void ADD_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*ADDW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*ADDB dst_reg, AL*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*ORW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*ORB dst_reg, AL*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*ORB dst_reg, src_reg*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*ORB dst_reg, src_reg*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (src_reg & 8) - { - if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x00); /*ADDB dst_reg, AL*/ - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*ADDB dst_reg, src_reg*/ - addbyte(0x00); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); } - else - fatal("!(dst_reg & src_reg & 8)\n"); + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x08); /*ORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*ORB dst_reg, src_reg*/ + addbyte(0x08); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x08); /*ORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x08); /*ORB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static __inline void ADD_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*ORW dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static __inline void ADD_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*ADDL dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - fatal("!(dst_reg & src_reg & 8)\n"); + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*ORL dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*ORL dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*ORL dst_reg, src_reg*/ + addbyte(0x09); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x09); /*ORW dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} +static __inline void +OR_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 0x10) { + addbyte(0x66); /*ORW host_reg, imm<<8*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xc8 | (host_reg & 7)); + addword(imm << 8); + } else if (host_reg & 8) { + addbyte(0x41); /*ORL host_reg, imm*/ + addbyte(0x81); + addbyte(0xc8 | (host_reg & 7)); + addlong(imm); + } else { + addbyte(0x81); /*ORL host_reg, imm*/ + addbyte(0xc8 | (host_reg & 7)); + addlong(imm); + } } -static __inline void SUB_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - if (!(src_reg & 0x10)) - { - addbyte(0x66); /*SHL AX, 8*/ - addbyte(0xc1); - addbyte(0xe0); - addbyte(8); - } - else - { - addbyte(0x66); /*AND AX, 0xff00*/ - addbyte(0x25); - addword(0xff00); - } - addbyte(0x66); /*SUBW dst_reg, AX*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7)); - } - else if (src_reg & 0x10) - { - addbyte(0x66); /*MOVW AX, src_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0xc0 | ((src_reg & 7) << 3)); - addbyte(0x66); /*SHR AX, 8*/ - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - addbyte(0x41); /*SUBB dst_reg, AL*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7)); - } - else - { - addbyte(0x45); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*XORW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*XORB dst_reg, AL*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*XORB dst_reg, src_reg*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (dst_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0x66); /*SHL src_reg, 8*/ - addbyte(0xc1); - addbyte(0xe0 | src_reg); - addbyte(0x08); - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*XORB dst_reg, src_reg*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else if (src_reg & 8) - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x41); /*MOVZX EBX, src_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x44); /*SUBB dst_reg, src_reg*/ - addbyte(0x28); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); } - else - { - if (dst_reg & 0x10) - { - addbyte(0xc1); /*SHR dst_reg, 8*/ - addbyte(0xe8 | (dst_reg & 7)); - addbyte(8); - } - if (src_reg & 0x10) - { - addbyte(0x0f); /*MOVZX EBX, src_reg*/ - addbyte(0xb7); - addbyte(0xd8 | (src_reg & 7)); - addbyte(0xc1); /*SHR EBX, 8*/ - addbyte(0xeb); - addbyte(8); - addbyte(0x28); /*SUBB dst_reg, EBX*/ - addbyte(0xd8 | (dst_reg & 7)); - } - else - { - addbyte(0x28); /*SUBB dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x30); /*XORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*XORB dst_reg, src_reg*/ + addbyte(0x30); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x30); /*XORB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x30); /*XORB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static __inline void SUB_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x45); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x41); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x44); - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*XORW dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } } -static __inline void SUB_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & src_reg & 8) - { - addbyte(0x45); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (dst_reg & 8) - { - addbyte(0x41); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else if (src_reg & 8) - { - addbyte(0x44); /*SUBL dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } - else - { - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); - } + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*XORL dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*XORL dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*XORW dst_reg, src_reg*/ + addbyte(0x31); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x31); /*XORW dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} +static __inline void +XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 0x10) { + addbyte(0x66); /*ORW host_reg, imm<<8*/ + addbyte(0x41); + addbyte(0x81); + addbyte(0xf0 | (host_reg & 7)); + addword(imm << 8); + } else if (host_reg & 8) { + addbyte(0x41); /*ORL host_reg, imm*/ + addbyte(0x81); + addbyte(0xf0 | (host_reg & 7)); + addlong(imm); + } else { + addbyte(0x81); /*ORL host_reg, imm*/ + addbyte(0xf0 | (host_reg & 7)); + addlong(imm); + } } -static __inline int CMP_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_B(int dst_reg, int src_reg) { - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = (dst_reg & 0x10) | REG_EDX; + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*ADDW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*ADDB dst_reg, AL*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*ADDB dst_reg, src_reg*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - - SUB_HOST_REG_B(dst_reg, src_reg); - - return dst_reg & ~0x10; + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*ADDB dst_reg, src_reg*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else if (src_reg & 8) { + if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x00); /*ADDB dst_reg, AL*/ + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x44); /*ADDB dst_reg, src_reg*/ + addbyte(0x00); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else + fatal("!(dst_reg & src_reg & 8)\n"); } -static __inline int CMP_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_W(int dst_reg, int src_reg) { - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_W(dst_reg, src_reg); - - return dst_reg; + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else + fatal("!(dst_reg & src_reg & 8)\n"); } -static __inline int CMP_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_L(int dst_reg, int src_reg) { - if (dst_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); - - dst_reg = REG_EDX; - } - - SUB_HOST_REG_L(dst_reg, src_reg); - - return dst_reg; + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*ADDL dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*ADDL dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*ADDL dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else + fatal("!(dst_reg & src_reg & 8)\n"); } -static __inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline void +SUB_HOST_REG_B(int dst_reg, int src_reg) { - if (host_reg & 0x10) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xC0 | (host_reg & 7)); - addword(imm << 8); + if (dst_reg & src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + if (!(src_reg & 0x10)) { + addbyte(0x66); /*SHL AX, 8*/ + addbyte(0xc1); + addbyte(0xe0); + addbyte(8); + } else { + addbyte(0x66); /*AND AX, 0xff00*/ + addbyte(0x25); + addword(0xff00); + } + addbyte(0x66); /*SUBW dst_reg, AX*/ + addbyte(0x41); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7)); + } else if (src_reg & 0x10) { + addbyte(0x66); /*MOVW AX, src_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | ((src_reg & 7) << 3)); + addbyte(0x66); /*SHR AX, 8*/ + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + addbyte(0x41); /*SUBB dst_reg, AL*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7)); + } else { + addbyte(0x45); /*SUBB dst_reg, src_reg*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*ADDB host_reg, imm*/ - addbyte(0xC0 | (host_reg & 7)); - addbyte(imm); + } else if (dst_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0x66); /*SHL src_reg, 8*/ + addbyte(0xc1); + addbyte(0xe0 | src_reg); + addbyte(0x08); + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x41); /*SUBB dst_reg, src_reg*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } + } else if (src_reg & 8) { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x41); /*MOVZX EBX, src_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x28); /*SUBB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x44); /*SUBB dst_reg, src_reg*/ + addbyte(0x28); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } else { + if (dst_reg & 0x10) { + addbyte(0xc1); /*SHR dst_reg, 8*/ + addbyte(0xe8 | (dst_reg & 7)); + addbyte(8); + } + if (src_reg & 0x10) { + addbyte(0x0f); /*MOVZX EBX, src_reg*/ + addbyte(0xb7); + addbyte(0xd8 | (src_reg & 7)); + addbyte(0xc1); /*SHR EBX, 8*/ + addbyte(0xeb); + addbyte(8); + addbyte(0x28); /*SUBB dst_reg, EBX*/ + addbyte(0xd8 | (dst_reg & 7)); + } else { + addbyte(0x28); /*SUBB dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } + } } -static __inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline void +SUB_HOST_REG_W(int dst_reg, int src_reg) { + if (dst_reg & src_reg & 8) { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x45); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x41); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x44); + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} +static __inline void +SUB_HOST_REG_L(int dst_reg, int src_reg) +{ + if (dst_reg & src_reg & 8) { + addbyte(0x45); /*SUBL dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (dst_reg & 8) { + addbyte(0x41); /*SUBL dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else if (src_reg & 8) { + addbyte(0x44); /*SUBL dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } else { + addbyte(0x29); /*SUBL dst_reg, src_reg*/ + addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + } +} + +static __inline int +CMP_HOST_REG_B(int dst_reg, int src_reg) +{ + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = (dst_reg & 0x10) | REG_EDX; + } + + SUB_HOST_REG_B(dst_reg, src_reg); + + return dst_reg & ~0x10; +} +static __inline int +CMP_HOST_REG_W(int dst_reg, int src_reg) +{ + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + SUB_HOST_REG_W(dst_reg, src_reg); + + return dst_reg; +} +static __inline int +CMP_HOST_REG_L(int dst_reg, int src_reg) +{ + if (dst_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((dst_reg & 7) << 3) | REG_EDX); + + dst_reg = REG_EDX; + } + + SUB_HOST_REG_L(dst_reg, src_reg); + + return dst_reg; +} + +static __inline void +ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +{ + if (host_reg & 0x10) { addbyte(0x66); /*ADDW host_reg, imm*/ if (host_reg & 8) - addbyte(0x41); + addbyte(0x41); addbyte(0x81); addbyte(0xC0 | (host_reg & 7)); - addword(imm); -} -static __inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ + addword(imm << 8); + } else { if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*ADDL host_reg, imm*/ + addbyte(0x41); + addbyte(0x80); /*ADDB host_reg, imm*/ addbyte(0xC0 | (host_reg & 7)); - addlong(imm); + addbyte(imm); + } +} +static __inline void +ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + addbyte(0x66); /*ADDW host_reg, imm*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); + addbyte(0xC0 | (host_reg & 7)); + addword(imm); +} +static __inline void +ADD_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); /*ADDL host_reg, imm*/ + addbyte(0xC0 | (host_reg & 7)); + addlong(imm); } -static __inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) -{ - if (host_reg & 0x10) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); - addbyte(0xE8 | (host_reg & 7)); - addword(imm << 8); - } - else - { - if (host_reg & 8) - addbyte(0x41); - addbyte(0x80); /*SUBB host_reg, imm*/ - addbyte(0xE8 | (host_reg & 7)); - addbyte(imm); - } -} -static __inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline void +SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) { + if (host_reg & 0x10) { addbyte(0x66); /*SUBW host_reg, imm*/ if (host_reg & 8) - addbyte(0x41); + addbyte(0x41); addbyte(0x81); addbyte(0xE8 | (host_reg & 7)); - addword(imm); -} -static __inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ + addword(imm << 8); + } else { if (host_reg & 8) - addbyte(0x41); - addbyte(0x81); /*SUBL host_reg, imm*/ + addbyte(0x41); + addbyte(0x80); /*SUBB host_reg, imm*/ addbyte(0xE8 | (host_reg & 7)); - addlong(imm); + addbyte(imm); + } +} +static __inline void +SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + addbyte(0x66); /*SUBW host_reg, imm*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); + addbyte(0xE8 | (host_reg & 7)); + addword(imm); +} +static __inline void +SUB_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x81); /*SUBL host_reg, imm*/ + addbyte(0xE8 | (host_reg & 7)); + addlong(imm); } -static __inline void INC_HOST_REG_W(int host_reg) +static __inline void +INC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*INCW host_reg*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); - addbyte(0xc0 | (host_reg & 7)); + addbyte(0x66); /*INCW host_reg*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); + addbyte(0xc0 | (host_reg & 7)); } -static __inline void INC_HOST_REG(int host_reg) +static __inline void +INC_HOST_REG(int host_reg) { - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); /*INCL host_reg*/ - addbyte(0xc0 | (host_reg & 7)); + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); /*INCL host_reg*/ + addbyte(0xc0 | (host_reg & 7)); } -static __inline void DEC_HOST_REG_W(int host_reg) +static __inline void +DEC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*DECW host_reg*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); - addbyte(0xc8 | (host_reg & 7)); + addbyte(0x66); /*DECW host_reg*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); + addbyte(0xc8 | (host_reg & 7)); } -static __inline void DEC_HOST_REG(int host_reg) +static __inline void +DEC_HOST_REG(int host_reg) { - if (host_reg & 8) - addbyte(0x41); - addbyte(0xff); /*DECL host_reg*/ - addbyte(0xc8 | (host_reg & 7)); + if (host_reg & 8) + addbyte(0x41); + addbyte(0xff); /*DECL host_reg*/ + addbyte(0xc8 | (host_reg & 7)); } -static __inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline int +CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = (host_reg & 0x10) | REG_EDX; - } - - SUB_HOST_REG_IMM_B(host_reg, imm); - - return host_reg; -} -static __inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM_W(host_reg, imm); - - return host_reg; -} -static __inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) -{ - if (host_reg & 8) - { - addbyte(0x44); /*MOV EDX, dst_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - - host_reg = REG_EDX; - } - - SUB_HOST_REG_IMM(host_reg, imm); - - return host_reg; -} - -static __inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} -static __inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_BP].l)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static __inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - -static __inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static __inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static __inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static __inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - if (host_reg & 8) - addbyte(0x41); - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | (host_reg & 7)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static __inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - uint8_t *jump1; - - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - CALL_FUNC((uintptr_t)CF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - - if (!not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - if (not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; -} - -static __inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static __inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - uint8_t *jump1; - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(timing_bt ? 4 : 0)); - if (!not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - if (not) - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; -} - -static __inline int LOAD_VAR_W(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x0f); /*MOVZX host_reg,[reg]*/ - addbyte(0xb7); - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/ - addbyte(0xb7); - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} -static __inline int LOAD_VAR_WL(uintptr_t addr) -{ - return LOAD_VAR_W(addr); -} -static __inline int LOAD_VAR_L(uintptr_t addr) -{ - int host_reg = REG_EBX; - - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte(addr - (uintptr_t)&cpu_state - 128); - } - else if (IS_32_ADDR(addr)) - { - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x25); - addlong((uint32_t)addr); - } - else - { - addbyte(0x48); /*MOV host_reg, &addr*/ - addbyte(0xb8 | host_reg); - addquad(addr); - addbyte(0x8b); /*MOVL host_reg, [host_reg]*/ - addbyte(host_reg | (host_reg << 3)); - } - - return host_reg; -} - -static __inline int COPY_REG(int src_reg) -{ - if (src_reg & 8) - addbyte(0x44); + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ addbyte(0x89); - addbyte(0xc0 | REG_ECX | ((src_reg & 7) << 3)); + addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - return REG_ECX | (src_reg & 0x10); + host_reg = (host_reg & 0x10) | REG_EDX; + } + + SUB_HOST_REG_IMM_B(host_reg, imm); + + return host_reg; } - -static __inline int LOAD_HOST_REG(int host_reg) +static __inline int +CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) { - if (host_reg & 8) - addbyte(0x44); + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ addbyte(0x89); - addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3)); + addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); - return REG_EBX | (host_reg & 0x10); + host_reg = REG_EDX; + } + + SUB_HOST_REG_IMM_W(host_reg, imm); + + return host_reg; +} +static __inline int +CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) +{ + if (host_reg & 8) { + addbyte(0x44); /*MOV EDX, dst_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3) | REG_EDX); + + host_reg = REG_EDX; + } + + SUB_HOST_REG_IMM(host_reg, imm); + + return host_reg; } -static __inline int ZERO_EXTEND_W_B(int reg) +static __inline void +LOAD_STACK_TO_EA(int off) { - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[ESP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static __inline int ZERO_EXTEND_L_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVZX EAX, AH*/ - addbyte(0xb6); - addbyte(0xc4); - - return REG_EAX; - } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static __inline int ZERO_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVZX regl, regw*/ + } else { + addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ addbyte(0xb7); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} - -static __inline int SIGN_EXTEND_W_B(int reg) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; + } } -static __inline int SIGN_EXTEND_L_B(int reg) +static __inline void +LOAD_EBP_TO_EA(int off) { - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | (reg << 3)); - addbyte(0x0f); /*MOVSX EAX, AH*/ - addbyte(0xbe); - addbyte(0xc4); - - return REG_EAX; + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[EBP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_EBP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); } - - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; -} -static __inline int SIGN_EXTEND_L_W(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | (reg & 7)); - - return REG_EAX; + } else { + addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ + addbyte(0xb7); + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_BP].l)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); + } + } } -static __inline void SHL_B_IMM(int reg, int count) +static __inline void +SP_MODIFY(int off) { - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHL AH, count*/ - addbyte(0xe0 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + if (stack32) { + if (off < 0x80) { + addbyte(0x83); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addbyte(off); + } else { + addbyte(0x81); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addlong(off); } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); + } else { + if (off < 0x80) { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x83); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addbyte(off); + } else { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x81); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addword(off); } -} -static __inline void SHL_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHL reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static __inline void SHL_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x20); - addbyte(count); -} -static __inline void SHR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SHR AH, count*/ - addbyte(0xe8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); - } -} -static __inline void SHR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SHR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static __inline void SHR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x28); - addbyte(count); -} -static __inline void SAR_B_IMM(int reg, int count) -{ - if (reg & 0x10) - { - addbyte(0x44); /*MOV EAX, reg*/ - addbyte(0x89); - addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); - addbyte(0xc0); /*SAR AH, count*/ - addbyte(0xf8 | REG_AH); - addbyte(count); - addbyte(0x41); /*MOV reg, EAX*/ - addbyte(0x89); - addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); - } -} -static __inline void SAR_W_IMM(int reg, int count) -{ - addbyte(0x66); /*SAR reg, count*/ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); -} -static __inline void SAR_L_IMM(int reg, int count) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | (reg & 7) | 0x38); - addbyte(count); + } } -static __inline void NEG_HOST_REG_B(int reg) +static __inline void +TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { - if (reg & 0x10) - { - if (reg & 8) - addbyte(0x44); - addbyte(0x89); /*MOV BX, reg*/ - addbyte(0xc3 | ((reg & 7) << 3)); - addbyte(0xf6); /*NEG BH*/ - addbyte(0xdf); - if (reg & 8) - addbyte(0x41); - addbyte(0x89); /*MOV reg, BX*/ - addbyte(0xd8 | (reg & 7)); - } - else - { - if (reg & 8) - addbyte(0x41); - addbyte(0xf6); - addbyte(0xd8 | (reg & 7)); - } + addbyte(0x66); /*CMPW host_reg, 0*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static __inline void NEG_HOST_REG_W(int reg) +static __inline void +TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) { - addbyte(0x66); - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); -} -static __inline void NEG_HOST_REG_L(int reg) -{ - if (reg & 8) - addbyte(0x41); - addbyte(0xf7); - addbyte(0xd8 | (reg & 7)); + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } - -static __inline void FP_ENTER(void) +static __inline void +TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { - if (codegen_fpu_entered) - return; - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } + addbyte(0x66); /*CMPW host_reg, 0*/ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} +static __inline void +TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +{ + if (host_reg & 8) + addbyte(0x41); + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | (host_reg & 7)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) +{ + uint8_t *jump1; + + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + } else { + CALL_FUNC((uintptr_t) ZF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x75); /*JNZ +*/ + } + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + CALL_FUNC((uintptr_t) CF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (timing_bt ? 4 : 0)); - codegen_fpu_entered = 1; + if (!not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; } -static __inline void FP_FXCH(int reg) +static __inline void +BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) +{ + uint8_t *jump1; + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + } else { + CALL_FUNC((uintptr_t) ZF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x75); /*JNZ +*/ + } + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + if (!not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (not ) + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; +} + +static __inline int +LOAD_VAR_W(uintptr_t addr) +{ + int host_reg = REG_EBX; + + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x0f); /*MOVZX host_reg, offset[cpu_state]*/ + addbyte(0xb7); + addbyte(0x45 | (host_reg << 3)); + addbyte(addr - (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x0f); /*MOVZX host_reg,[reg]*/ + addbyte(0xb7); + addbyte(0x04 | (host_reg << 3)); + addbyte(0x25); + addlong((uint32_t) addr); + } else { + addbyte(0x48); /*MOV host_reg, &addr*/ + addbyte(0xb8 | host_reg); + addquad(addr); + addbyte(0x0f); /*MOVZX host_reg, [host_reg]*/ + addbyte(0xb7); + addbyte(host_reg | (host_reg << 3)); + } + + return host_reg; +} +static __inline int +LOAD_VAR_WL(uintptr_t addr) +{ + return LOAD_VAR_W(addr); +} +static __inline int +LOAD_VAR_L(uintptr_t addr) +{ + int host_reg = REG_EBX; + + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x8b); /*MOVL host_reg, offset[cpu_state]*/ + addbyte(0x45 | (host_reg << 3)); + addbyte(addr - (uintptr_t) &cpu_state - 128); + } else if (IS_32_ADDR(addr)) { + addbyte(0x8b); /*MOVL host_reg,[reg]*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(0x25); + addlong((uint32_t) addr); + } else { + addbyte(0x48); /*MOV host_reg, &addr*/ + addbyte(0xb8 | host_reg); + addquad(addr); + addbyte(0x8b); /*MOVL host_reg, [host_reg]*/ + addbyte(host_reg | (host_reg << 3)); + } + + return host_reg; +} + +static __inline int +COPY_REG(int src_reg) +{ + if (src_reg & 8) + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | REG_ECX | ((src_reg & 7) << 3)); + + return REG_ECX | (src_reg & 0x10); +} + +static __inline int +LOAD_HOST_REG(int host_reg) +{ + if (host_reg & 8) + addbyte(0x44); + addbyte(0x89); + addbyte(0xc0 | REG_EBX | ((host_reg & 7) << 3)); + + return REG_EBX | (host_reg & 0x10); +} + +static __inline int +ZERO_EXTEND_W_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVZX EAX, AH*/ + addbyte(0xb6); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +ZERO_EXTEND_L_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVZX EAX, AH*/ + addbyte(0xb6); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +ZERO_EXTEND_L_W(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVZX regl, regw*/ + addbyte(0xb7); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} + +static __inline int +SIGN_EXTEND_W_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVSX EAX, AH*/ + addbyte(0xbe); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +SIGN_EXTEND_L_B(int reg) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | (reg << 3)); + addbyte(0x0f); /*MOVSX EAX, AH*/ + addbyte(0xbe); + addbyte(0xc4); + + return REG_EAX; + } + + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} +static __inline int +SIGN_EXTEND_L_W(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0x0f); /*MOVSX regl, regw*/ + addbyte(0xbf); + addbyte(0xc0 | (reg & 7)); + + return REG_EAX; +} + +static __inline void +SHL_B_IMM(int reg, int count) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); + addbyte(0xc0); /*SHL AH, count*/ + addbyte(0xe0 | REG_AH); + addbyte(count); + addbyte(0x41); /*MOV reg, EAX*/ + addbyte(0x89); + addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xc0); /*SHL reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x20); + addbyte(count); + } +} +static __inline void +SHL_W_IMM(int reg, int count) +{ + addbyte(0x66); /*SHL reg, count*/ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); + addbyte(0xc0 | (reg & 7) | 0x20); + addbyte(count); +} +static __inline void +SHL_L_IMM(int reg, int count) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); /*SHL reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x20); + addbyte(count); +} +static __inline void +SHR_B_IMM(int reg, int count) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); + addbyte(0xc0); /*SHR AH, count*/ + addbyte(0xe8 | REG_AH); + addbyte(count); + addbyte(0x41); /*MOV reg, EAX*/ + addbyte(0x89); + addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xc0); /*SHR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x28); + addbyte(count); + } +} +static __inline void +SHR_W_IMM(int reg, int count) +{ + addbyte(0x66); /*SHR reg, count*/ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); + addbyte(0xc0 | (reg & 7) | 0x28); + addbyte(count); +} +static __inline void +SHR_L_IMM(int reg, int count) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); /*SHR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x28); + addbyte(count); +} +static __inline void +SAR_B_IMM(int reg, int count) +{ + if (reg & 0x10) { + addbyte(0x44); /*MOV EAX, reg*/ + addbyte(0x89); + addbyte(0xc0 | REG_EAX | ((reg & 7) << 3)); + addbyte(0xc0); /*SAR AH, count*/ + addbyte(0xf8 | REG_AH); + addbyte(count); + addbyte(0x41); /*MOV reg, EAX*/ + addbyte(0x89); + addbyte(0xc0 | (REG_EAX << 3) | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xc0); /*SAR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x38); + addbyte(count); + } +} +static __inline void +SAR_W_IMM(int reg, int count) +{ + addbyte(0x66); /*SAR reg, count*/ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); + addbyte(0xc0 | (reg & 7) | 0x38); + addbyte(count); +} +static __inline void +SAR_L_IMM(int reg, int count) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xc1); /*SAR reg, count*/ + addbyte(0xc0 | (reg & 7) | 0x38); + addbyte(count); +} + +static __inline void +NEG_HOST_REG_B(int reg) +{ + if (reg & 0x10) { + if (reg & 8) + addbyte(0x44); + addbyte(0x89); /*MOV BX, reg*/ + addbyte(0xc3 | ((reg & 7) << 3)); + addbyte(0xf6); /*NEG BH*/ + addbyte(0xdf); + if (reg & 8) + addbyte(0x41); + addbyte(0x89); /*MOV reg, BX*/ + addbyte(0xd8 | (reg & 7)); + } else { + if (reg & 8) + addbyte(0x41); + addbyte(0xf6); + addbyte(0xd8 | (reg & 7)); + } +} +static __inline void +NEG_HOST_REG_W(int reg) +{ + addbyte(0x66); + if (reg & 8) + addbyte(0x41); + addbyte(0xf7); + addbyte(0xd8 | (reg & 7)); +} +static __inline void +NEG_HOST_REG_L(int reg) +{ + if (reg & 8) + addbyte(0x41); + addbyte(0xf7); + addbyte(0xd8 | (reg & 7)); +} + +static __inline void +FP_ENTER(void) +{ + if (codegen_fpu_entered) + return; + if (IS_32_ADDR(&cr0)) { + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x04); + addbyte(0x25); + addlong((uintptr_t) &cr0); + addbyte(0x0c); + } else { + addbyte(0x48); /*MOV RAX, &cr0*/ + addbyte(0xb8 | REG_EAX); + addquad((uint64_t) &cr0); + addbyte(0xf6); /*TEST [RAX], 0xc*/ + addbyte(0 | (REG_EAX << 3)); + addbyte(0x0c); + } + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + 12 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + load_param_1_32(&codeblock[block_current], 7); + CALL_FUNC((uintptr_t) x86_int); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + + codegen_fpu_entered = 1; +} + +static __inline void +FP_FXCH(int reg) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + + addbyte(0x48); /*MOV RDX, ST[RBX*8]*/ + addbyte(0x8b); + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + addbyte(0x48); /*MOV RCX, ST[RAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x48); /*MOV ST[RAX*8], RDX*/ + addbyte(0x89); + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x48); /*MOV ST[RBX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0x8a); /*MOV CL, tag[EAX]*/ + addbyte(0x4c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x8a); /*MOV DL, tag[EBX]*/ + addbyte(0x54); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x88); /*MOV tag[EBX], CL*/ + addbyte(0x4c); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x88); /*MOV tag[EAX], DL*/ + addbyte(0x54); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + + addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ + addbyte(0x8b); + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x48); /*MOV MM[RAX*8], RDX*/ + addbyte(0x89); + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x48); /*MOV MM[RBX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); +} + +static __inline void +FP_FLD(int reg) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (reg) { addbyte(0x83); /*ADD EAX, reg*/ addbyte(0xc0); addbyte(reg); - - addbyte(0x48); /*MOV RDX, ST[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); addbyte(0x83); /*AND EAX, 7*/ addbyte(0xe0); addbyte(0x07); - addbyte(0x48); /*MOV RCX, ST[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); + } else { + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + } - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(0x07); + addbyte(0x48); /*MOV RDX, ST_i64[EAX*8]*/ + addbyte(0x8b); + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x8a); /*MOV AL, [tag+EAX]*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(0x48); /*MOV ST[EBX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ + addbyte(0x89); + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); - addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RAX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x48); /*MOV MM[RBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); + addbyte(0x89); /*MOV [TOP], EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); } - - -static __inline void FP_FLD(int reg) +static __inline void +FP_FST(int reg) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ + addbyte(0x8b); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [tag+EAX]*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); addbyte(0x07); - addbyte(0x48); /*MOV RDX, ST_i64[EAX*8]*/ - addbyte(0x8b); - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(0x48); /*MOV ST[EBX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ - addbyte(0x89); - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + } - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); + addbyte(0x48); /*MOV ST[EAX*8], RCX*/ + addbyte(0x89); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EAX], BL*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); } -static __inline void FP_FST(int reg) +static __inline void +FP_POP(void) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ - addbyte(0x8b); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0x48); /*MOV ST[EAX*8], RCX*/ - addbyte(0x89); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(3); + addbyte(0x83); /*ADD AL, 1*/ + addbyte(0xc0); + addbyte(1); + addbyte(0x83); /*AND AL, 7*/ + addbyte(0xe0); + addbyte(7); + addbyte(0x89); /*MOV [TOP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); +} +static __inline void +FP_POP2(void) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(3); + addbyte(0x83); /*ADD AL, 2*/ + addbyte(0xc0); + addbyte(2); + addbyte(0x83); /*AND AL, 7*/ + addbyte(0xe0); + addbyte(7); + addbyte(0x89); /*MOV [TOP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); } -static __inline void FP_POP(void) +static __inline void +FP_LOAD_S(void) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 1*/ - addbyte(0xc0); - addbyte(1); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVD XMM0, EAX*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf3); /*CVTSS2SD XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static __inline void FP_POP2(void) +static __inline void +FP_LOAD_D(void) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(3); - addbyte(0x83); /*ADD AL, 2*/ - addbyte(0xc0); - addbyte(2); - addbyte(0x83); /*AND AL, 7*/ - addbyte(0xe0); - addbyte(7); - addbyte(0x89); /*MOV [TOP], EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x48); /*TEST RAX, RAX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ + addbyte(0x89); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static __inline void FP_LOAD_S(void) +static __inline void +FP_LOAD_IW(void) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf3); /*CVTSS2SD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x0f); /*MOVSX EAX, AX*/ + addbyte(0xbf); + addbyte(0xc0); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static __inline void FP_LOAD_D(void) +static __inline void +FP_LOAD_IL(void) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); +} +static __inline void +FP_LOAD_IQ(void) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0xf2); /*CVTSI2SDQ XMM0, RAX*/ + addbyte(0x48); + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc0); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x48); /*TEST RAX, RAX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0x48); /*MOV [ST_i64+EBX*8], RAX*/ + addbyte(0x89); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); } -static __inline void FP_LOAD_IW(void) +static __inline void +FP_LOAD_IMM_Q(uint64_t v) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static __inline void FP_LOAD_IL(void) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SD XMM0, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x85); /*TEST EAX, EAX*/ - addbyte(0xc0); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0f); /*SETE [tag+EBX]*/ - addbyte(0x94); - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); -} -static __inline void FP_LOAD_IQ(void) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0xf2); /*CVTSI2SDQ XMM0, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc0); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0x48); /*TEST RAX, RAX*/ - addbyte(0x85); - addbyte(0xc0); - addbyte(0x48); /*MOV [ST_i64+EBX*8], RAX*/ - addbyte(0x89); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x0f); /*SETE AL*/ - addbyte(0x94); - addbyte(0xc0); - addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x0c); /*OR AL, TAG_UINT64*/ - addbyte(TAG_UINT64); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addlong(v & 0xffffffff); + addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST) + 4); + addlong(v >> 32); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(v ? 0 : 1); } -static __inline void FP_LOAD_IMM_Q(uint64_t v) +static __inline void +FP_FCHS(void) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addlong(v & 0xffffffff); - addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST) + 4); - addlong(v >> 32); - addbyte(0x89); /*MOV TOP, EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(v ? 0 : 1); + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xf2); /*SUBSD XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0xc0); + addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ + addbyte(0x0f); + addbyte(0x11); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); } -static __inline void FP_FCHS(void) +static __inline int +FP_LOAD_REG(int reg) { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf2); /*SUBSD XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc0); - addbyte(0xf2); /*SUBSD XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0x11); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); -} - -static __inline int FP_LOAD_REG(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc0); - addbyte(0x66); /*MOVD EBX, XMM0*/ - addbyte(0x0f); - addbyte(0x7e); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ addbyte(0xc0 | REG_EBX); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe0 | REG_EBX); + addbyte(0x07); + } + addbyte(0xf3); /*MOVQ XMM0, ST[EBX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc0); + addbyte(0x66); /*MOVD EBX, XMM0*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0xc0 | REG_EBX); - return REG_EBX; + return REG_EBX; } -static __inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +static __inline void +FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x48); /*MOV RBX, ST[EBX*8]*/ - addbyte(0x8b); - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc0 | REG_EBX); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe0 | REG_EBX); + addbyte(0x07); + } + addbyte(0x48); /*MOV RBX, ST[EBX*8]*/ + addbyte(0x8b); + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); - *host_reg1 = REG_EBX; + *host_reg1 = REG_EBX; } -static __inline int64_t x87_fround16_64(double b) +static __inline int64_t +x87_fround16_64(double b) { - int16_t a, c; + int16_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int16_t)floor(b); - c = (int16_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return (int64_t) a; - else if ((b - a) > (c - b)) - return (int64_t) c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)((int16_t)floor(b)); - case 2: /*Up*/ - return (int64_t)((int16_t)ceil(b)); - case 3: /*Chop*/ - return (int64_t)((int16_t)b); - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int16_t) floor(b); + c = (int16_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return (int64_t) a; + else if ((b - a) > (c - b)) + return (int64_t) c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) ((int16_t) floor(b)); + case 2: /*Up*/ + return (int64_t) ((int16_t) ceil(b)); + case 3: /*Chop*/ + return (int64_t) ((int16_t) b); + } - return 0; + return 0; } -static __inline int64_t x87_fround32_64(double b) +static __inline int64_t +x87_fround32_64(double b) { - int32_t a, c; + int32_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int32_t)floor(b); - c = (int32_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return (int64_t) a; - else if ((b - a) > (c - b)) - return (int64_t) c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)((int32_t)floor(b)); - case 2: /*Up*/ - return (int64_t)((int32_t)ceil(b)); - case 3: /*Chop*/ - return (int64_t)((int32_t)b); - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int32_t) floor(b); + c = (int32_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return (int64_t) a; + else if ((b - a) > (c - b)) + return (int64_t) c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) ((int32_t) floor(b)); + case 2: /*Up*/ + return (int64_t) ((int32_t) ceil(b)); + case 3: /*Chop*/ + return (int64_t) ((int32_t) b); + } - return 0; + return 0; } -static __inline int64_t x87_fround(double b) +static __inline int64_t +x87_fround(double b) { - int64_t a, c; + int64_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } - return 0; + return 0; } -static __inline int FP_LOAD_REG_INT_W(int reg) +static __inline int +FP_LOAD_REG_INT_W(int reg) { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); - CALL_FUNC((uintptr_t)x87_fround16_64); + CALL_FUNC((uintptr_t) x87_fround16_64); - addbyte(0x93); /*XCHG EBX, EAX*/ + addbyte(0x93); /*XCHG EBX, EAX*/ - return REG_EBX; + return REG_EBX; } -static __inline int FP_LOAD_REG_INT(int reg) +static __inline int +FP_LOAD_REG_INT(int reg) { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); - CALL_FUNC((uintptr_t)x87_fround32_64); + CALL_FUNC((uintptr_t) x87_fround32_64); - addbyte(0x93); /*XCHG EBX, EAX*/ + addbyte(0x93); /*XCHG EBX, EAX*/ - return REG_EBX; + return REG_EBX; } -static __inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +static __inline void +FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) { - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ - addbyte(0x8b); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0x48); /*XCHG RBX, RAX*/ - addbyte(0x93); - - *host_reg1 = REG_EBX; - - return; - } - - addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_UINT64); - - addbyte(0x74); /*JZ +*/ - addbyte(5+2); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) { + /*If we know the register was loaded with FILDq in this block and + has not been modified, then we can skip most of the conversion + and just load the 64-bit integer representation directly */ addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ addbyte(0x8b); addbyte(0x44); addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - - addbyte(0xeb); /*JMP done*/ - addbyte(6+12); - - addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - - CALL_FUNC((uintptr_t)x87_fround); + addbyte((uint8_t) cpu_state_offset(MM)); addbyte(0x48); /*XCHG RBX, RAX*/ addbyte(0x93); *host_reg1 = REG_EBX; + + return; + } + + addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(TAG_UINT64); + + addbyte(0x74); /*JZ +*/ + addbyte(5 + 2); + + addbyte(0x48); /*MOV RAX, [ST_i64+EAX*8]*/ + addbyte(0x8b); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + + addbyte(0xeb); /*JMP done*/ + addbyte(6 + 12); + + addbyte(0xf3); /*MOVQ XMM0, ST[EAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + + CALL_FUNC((uintptr_t) x87_fround); + + addbyte(0x48); /*XCHG RBX, RAX*/ + addbyte(0x93); + + *host_reg1 = REG_EBX; } #define FPU_ADD 0 @@ -4526,1793 +4155,1695 @@ static __inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) #define FPU_SUB 2 #define FPU_SUBR 3 -static __inline void FP_OP_REG(int op, int dst, int src) +static __inline void +FP_OP_REG(int op, int dst, int src) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (dst) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - if (src) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc0 | REG_EBX); - addbyte(src); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe0 | REG_EBX); - addbyte(0x07); - } - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_NOT_UINT64); - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - break; - } - addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (dst) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } + if (src) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc0 | REG_EBX); + addbyte(src); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe0 | REG_EBX); + addbyte(0x07); + } + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(TAG_NOT_UINT64); + if (op == FPU_DIVR || op == FPU_SUBR) { + addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } + switch (op) { + case FPU_ADD: + addbyte(0xf2); /*ADDSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x58); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_DIV: + addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_DIVR: + addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_MUL: + addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x59); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_SUB: + addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + case FPU_SUBR: + addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + break; + } + addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); +} + +static __inline void +FP_OP_MEM(int op) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag)); + addbyte(TAG_NOT_UINT64); + + switch (op) { + case FPU_ADD: + addbyte(0xf2); /*ADDSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x58); + addbyte(0xc1); + break; + case FPU_DIV: + addbyte(0xf2); /*DIVSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0xc1); + break; + case FPU_DIVR: + addbyte(0xf2); /*DIVSD XMM1, XMM0*/ + addbyte(0x0f); + addbyte(0x5e); + addbyte(0xc8); + break; + case FPU_MUL: + addbyte(0xf2); /*MULSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x59); + addbyte(0xc1); + break; + case FPU_SUB: + addbyte(0xf2); /*SUBSD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0xc1); + break; + case FPU_SUBR: + addbyte(0xf2); /*SUBSD XMM1, XMM0*/ + addbyte(0x0f); + addbyte(0x5c); + addbyte(0xc8); + break; + } + if (op == FPU_DIVR || op == FPU_SUBR) { + addbyte(0x66); /*MOVQ ST[RAX*8], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0x66); /*MOVQ ST[RAX*8], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x44); addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static __inline void FP_OP_MEM(int op) +static __inline void +FP_OP_S(int op) { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); + addbyte(0x66); /*MOVD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc9); + FP_OP_MEM(op); +} +static __inline void +FP_OP_D(int op) +{ + addbyte(0x66); /*MOVQ XMM1, RAX*/ + addbyte(0x48); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0x0f); /*STMXCSR [ESP+8]*/ + addbyte(0xae); + addbyte(0x5c); + addbyte(0x24); + addbyte(0x08); + addbyte(0x8b); /*MOV EAX, [ESP+8]*/ addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag)); - addbyte(TAG_NOT_UINT64); - - switch (op) - { - case FPU_ADD: - addbyte(0xf2); /*ADDSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x58); - addbyte(0xc1); - break; - case FPU_DIV: - addbyte(0xf2); /*DIVSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc1); - break; - case FPU_DIVR: - addbyte(0xf2); /*DIVSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5e); - addbyte(0xc8); - break; - case FPU_MUL: - addbyte(0xf2); /*MULSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x59); - addbyte(0xc1); - break; - case FPU_SUB: - addbyte(0xf2); /*SUBSD XMM0, XMM1*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc1); - break; - case FPU_SUBR: - addbyte(0xf2); /*SUBSD XMM1, XMM0*/ - addbyte(0x0f); - addbyte(0x5c); - addbyte(0xc8); - break; - } - if (op == FPU_DIVR || op == FPU_SUBR) - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0x66); /*MOVQ ST[RAX*8], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } + addbyte(0x24); + addbyte(0x08); + addbyte(0x25); /*AND EAX, ~(3 << 13)*/ + addlong(~(3 << 10)); + addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/ + addlong((cpu_state.npxc & (3 << 10)) << 3); + addbyte(0x89); /*MOV [RSP+12], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x0c); + addbyte(0x0f); /*LDMXCSR [RSP+12]*/ + addbyte(0xae); + addbyte(0x54); + addbyte(0x24); + addbyte(0x0c); + } + FP_OP_MEM(op); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0x0f); /*LDMXCSR [RSP+8]*/ + addbyte(0xae); + addbyte(0x54); + addbyte(0x24); + addbyte(0x08); + } +} +static __inline void +FP_OP_IW(int op) +{ + addbyte(0x0f); /*MOVSX EAX, AX*/ + addbyte(0xbf); + addbyte(0xc0); + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_OP_MEM(op); +} +static __inline void +FP_OP_IL(int op) +{ + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_OP_MEM(op); } -static __inline void FP_OP_S(int op) +static __inline void +FP_COMPARE_REG(int dst, int src) { - addbyte(0x66); /*MOVD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ - addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_OP_MEM(op); -} -static __inline void FP_OP_D(int op) -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*STMXCSR [ESP+8]*/ - addbyte(0xae); - addbyte(0x5c); - addbyte(0x24); - addbyte(0x08); - addbyte(0x8b); /*MOV EAX, [ESP+8]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x08); - addbyte(0x25); /*AND EAX, ~(3 << 13)*/ - addlong(~(3 << 10)); - addbyte(0x0d); /*OR EAX, (npxc & (3 << 10)) << 3*/ - addlong((cpu_state.npxc & (3 << 10)) << 3); - addbyte(0x89); /*MOV [RSP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x0c); - addbyte(0x0f); /*LDMXCSR [RSP+12]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x0c); - } - FP_OP_MEM(op); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0x0f); /*LDMXCSR [RSP+8]*/ - addbyte(0xae); - addbyte(0x54); - addbyte(0x24); - addbyte(0x08); - } -} -static __inline void FP_OP_IW(int op) -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) { + addbyte(0x83); /*ADD EAX, 1*/ addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} -static __inline void FP_OP_IL(int op) -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_OP_MEM(op); -} + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } -static __inline void FP_COMPARE_REG(int dst, int src) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ - addbyte(0x0f); - addbyte(0x2f); - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} - -static __inline void FP_COMPARE_MEM(void) -{ - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + if (src) { + addbyte(0xf3); /*MOVQ XMM0, ST[RBX*8]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0x66); /*COMISD XMM0, XMM1*/ + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ addbyte(0x0f); addbyte(0x2f); - addbyte(0xc1); - addbyte(0x9f); /*LAHF*/ - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); -} -static __inline void FP_COMPARE_S(void) -{ - addbyte(0x66); /*MOVD XMM1, EAX*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ addbyte(0x0f); - addbyte(0x5a); - addbyte(0xc9); - FP_COMPARE_MEM(); -} -static __inline void FP_COMPARE_D(void) -{ - addbyte(0x66); /*MOVQ XMM1, RAX*/ - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static __inline void FP_COMPARE_IW(void) -{ - addbyte(0x0f); /*MOVSX EAX, AX*/ - addbyte(0xbf); - addbyte(0xc0); - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); -} -static __inline void FP_COMPARE_IL(void) -{ - addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ - addbyte(0x0f); - addbyte(0x2a); - addbyte(0xc8); - FP_COMPARE_MEM(); + addbyte(0x2f); + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + + addbyte(0x9f); /*LAHF*/ + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); } -static __inline void UPDATE_NPXC(int reg) +static __inline void +FP_COMPARE_MEM(void) +{ + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0x66); /*COMISD XMM0, XMM1*/ + addbyte(0x0f); + addbyte(0x2f); + addbyte(0xc1); + addbyte(0x9f); /*LAHF*/ + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); +} +static __inline void +FP_COMPARE_S(void) +{ + addbyte(0x66); /*MOVD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + addbyte(0xf3); /*CVTSS2SD XMM1, XMM1*/ + addbyte(0x0f); + addbyte(0x5a); + addbyte(0xc9); + FP_COMPARE_MEM(); +} +static __inline void +FP_COMPARE_D(void) +{ + addbyte(0x66); /*MOVQ XMM1, RAX*/ + addbyte(0x48); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc8); + FP_COMPARE_MEM(); +} +static __inline void +FP_COMPARE_IW(void) +{ + addbyte(0x0f); /*MOVSX EAX, AX*/ + addbyte(0xbf); + addbyte(0xc0); + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_COMPARE_MEM(); +} +static __inline void +FP_COMPARE_IL(void) +{ + addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ + addbyte(0x0f); + addbyte(0x2a); + addbyte(0xc8); + FP_COMPARE_MEM(); +} + +static __inline void +UPDATE_NPXC(int reg) { } -static __inline void SET_BITS(uintptr_t addr, uint32_t val) +static __inline void +SET_BITS(uintptr_t addr, uint32_t val) { - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); /*OR [addr], val*/ - addbyte(0x0c); - addbyte(0x25); - addlong(addr); - addbyte(val); - } + if (IS_32_ADDR(addr)) { + if (val & ~0xff) { + addbyte(0x81); /*OR [addr], val*/ + addbyte(0x0c); + addbyte(0x25); + addlong(addr); + addlong(val); + } else { + addbyte(0x80); /*OR [addr], val*/ + addbyte(0x0c); + addbyte(0x25); + addlong(addr); + addbyte(val); } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*OR [RAX], val*/ - addbyte(0x08); - addlong(val); - } - else - { - addbyte(0x80); /*OR [RAX], val*/ - addbyte(0x08); - addbyte(val); - } + } else { + addbyte(0x48); /*MOV RAX, &addr*/ + addbyte(0xb8 | REG_EAX); + addquad(addr); + if (val & ~0xff) { + addbyte(0x81); /*OR [RAX], val*/ + addbyte(0x08); + addlong(val); + } else { + addbyte(0x80); /*OR [RAX], val*/ + addbyte(0x08); + addbyte(val); } + } } -static __inline void CLEAR_BITS(uintptr_t addr, uint32_t val) +static __inline void +CLEAR_BITS(uintptr_t addr, uint32_t val) { - if (IS_32_ADDR(addr)) - { - if (val & ~0xff) - { - addbyte(0x81); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [addr], val*/ - addbyte(0x24); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } + if (IS_32_ADDR(addr)) { + if (val & ~0xff) { + addbyte(0x81); /*AND [addr], val*/ + addbyte(0x24); + addbyte(0x25); + addlong(addr); + addlong(~val); + } else { + addbyte(0x80); /*AND [addr], val*/ + addbyte(0x24); + addbyte(0x25); + addlong(addr); + addbyte(~val); } - else - { - addbyte(0x48); /*MOV RAX, &addr*/ - addbyte(0xb8 | REG_EAX); - addquad(addr); - if (val & ~0xff) - { - addbyte(0x81); /*AND [RAX], val*/ - addbyte(0x20); - addlong(~val); - } - else - { - addbyte(0x80); /*AND [RAX], val*/ - addbyte(0x20); - addbyte(~val); - } + } else { + addbyte(0x48); /*MOV RAX, &addr*/ + addbyte(0xb8 | REG_EAX); + addquad(addr); + if (val & ~0xff) { + addbyte(0x81); /*AND [RAX], val*/ + addbyte(0x20); + addlong(~val); + } else { + addbyte(0x80); /*AND [RAX], val*/ + addbyte(0x20); + addbyte(~val); } + } } #define LOAD_Q_REG_1 REG_EAX #define LOAD_Q_REG_2 REG_EDX -static __inline void MMX_ENTER(void) +static __inline void +MMX_ENTER(void) { - if (codegen_mmx_entered) - return; + if (codegen_mmx_entered) + return; - if (IS_32_ADDR(&cr0)) - { - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x04); - addbyte(0x25); - addlong((uintptr_t)&cr0); - addbyte(0x0c); - } - else - { - addbyte(0x48); /*MOV RAX, &cr0*/ - addbyte(0xb8 | REG_EAX); - addquad((uint64_t)&cr0); - addbyte(0xf6); /*TEST [RAX], 0xc*/ - addbyte(0 | (REG_EAX << 3)); - addbyte(0x0c); - } - addbyte(0x74); /*JZ +*/ - addbyte(7+5+12+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC((uintptr_t)x86_int); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (IS_32_ADDR(&cr0)) { + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x04); + addbyte(0x25); + addlong((uintptr_t) &cr0); + addbyte(0x0c); + } else { + addbyte(0x48); /*MOV RAX, &cr0*/ + addbyte(0xb8 | REG_EAX); + addquad((uint64_t) &cr0); + addbyte(0xf6); /*TEST [RAX], 0xc*/ + addbyte(0 | (REG_EAX << 3)); + addbyte(0x0c); + } + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + 12 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + load_param_1_32(&codeblock[block_current], 7); + CALL_FUNC((uintptr_t) x86_int); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x31); /*XOR EAX, EAX*/ + addbyte(0xc0); + addbyte(0xc6); /*MOV ISMMX, 1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ismmx)); + addbyte(1); + addbyte(0x89); /*MOV TOP, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV tag, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV tag+4, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[4])); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); - - codegen_mmx_entered = 1; + codegen_mmx_entered = 1; } extern int mmx_ebx_ecx_loaded; -static __inline int LOAD_MMX_D(int guest_reg) +static __inline int +LOAD_MMX_D(int guest_reg) { - int host_reg = REG_EBX; + int host_reg = REG_EBX; - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x44 | (host_reg << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x8b); /*MOV EBX, reg*/ + addbyte(0x44 | (host_reg << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); - return host_reg; + return host_reg; } -static __inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +static __inline void +LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) { - int host_reg = REG_EBX; + int host_reg = REG_EBX; - if (host_reg & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x8b); /*MOV RBX, reg*/ - addbyte(0x44 | ((host_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + if (host_reg & 8) + addbyte(0x4c); + else + addbyte(0x48); + addbyte(0x8b); /*MOV RBX, reg*/ + addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); - *host_reg1 = host_reg; + *host_reg1 = host_reg; } -static __inline int LOAD_MMX_Q_MMX(int guest_reg) +static __inline int +LOAD_MMX_Q_MMX(int guest_reg) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = 100; - addbyte(0xf3); /*MOV XMMx, reg*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x44 | ((dst_reg & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0xf3); /*MOV XMMx, reg*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x44 | ((dst_reg & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); - return dst_reg; + return dst_reg; } -static __inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +static __inline int +LOAD_INT_TO_MMX(int src_reg1, int src_reg2) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = 100; - addbyte(0x66); /*MOVQ host_reg, src_reg1*/ - if (src_reg1 & 8) - addbyte(0x49); - else - addbyte(0x48); - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | (src_reg1 & 7)); + addbyte(0x66); /*MOVQ host_reg, src_reg1*/ + if (src_reg1 & 8) + addbyte(0x49); + else + addbyte(0x48); + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0 | (dst_reg << 3) | (src_reg1 & 7)); - return dst_reg; + return dst_reg; } -static __inline void STORE_MMX_LQ(int guest_reg, int host_reg1) +static __inline void +STORE_MMX_LQ(int guest_reg, int host_reg1) { - addbyte(0xC7); /*MOVL [reg],0*/ + addbyte(0xC7); /*MOVL [reg],0*/ + addbyte(0x44); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); + addlong(0); + if (host_reg1 & 8) addbyte(0x44); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); - addlong(0); - if (host_reg1 & 8) - addbyte(0x44); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x44 | ((host_reg1 & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } -static __inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +static __inline void +STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) { - if (host_reg1 & 8) - addbyte(0x4c); - else - addbyte(0x48); - addbyte(0x89); /*MOV [reg],host_reg*/ - addbyte(0x44 | ((host_reg1 & 7) << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + if (host_reg1 & 8) + addbyte(0x4c); + else + addbyte(0x48); + addbyte(0x89); /*MOV [reg],host_reg*/ + addbyte(0x44 | ((host_reg1 & 7) << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } -static __inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) +static __inline void +STORE_MMX_Q_MMX(int guest_reg, int host_reg) { - addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x44 | (host_reg << 3)); - addbyte(0x25); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x44 | (host_reg << 3)); + addbyte(0x25); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); } -#define MMX_x86_OP(name, opcode) \ -static __inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} +#define MMX_x86_OP(name, opcode) \ + static __inline void MMX_##name(int dst_reg, int src_reg) \ + { \ + addbyte(0x66); /*op dst_reg, src_reg*/ \ + addbyte(0x0f); \ + addbyte(opcode); \ + addbyte(0xc0 | (dst_reg << 3) | src_reg); \ + } -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) +MMX_x86_OP(AND, 0xdb) + MMX_x86_OP(ANDN, 0xdf) + MMX_x86_OP(OR, 0xeb) + MMX_x86_OP(XOR, 0xef) -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) + MMX_x86_OP(ADDB, 0xfc) + MMX_x86_OP(ADDW, 0xfd) + MMX_x86_OP(ADDD, 0xfe) + MMX_x86_OP(ADDSB, 0xec) + MMX_x86_OP(ADDSW, 0xed) + MMX_x86_OP(ADDUSB, 0xdc) + MMX_x86_OP(ADDUSW, 0xdd) -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -MMX_x86_OP(SUBSW, 0xe9) -MMX_x86_OP(SUBUSB, 0xd8) -MMX_x86_OP(SUBUSW, 0xd9) + MMX_x86_OP(SUBB, 0xf8) + MMX_x86_OP(SUBW, 0xf9) + MMX_x86_OP(SUBD, 0xfa) + MMX_x86_OP(SUBSB, 0xe8) + MMX_x86_OP(SUBSW, 0xe9) + MMX_x86_OP(SUBUSB, 0xd8) + MMX_x86_OP(SUBUSW, 0xd9) -MMX_x86_OP(PUNPCKLBW, 0x60); + MMX_x86_OP(PUNPCKLBW, 0x60); MMX_x86_OP(PUNPCKLWD, 0x61); MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); +MMX_x86_OP(PCMPGTB, 0x64); +MMX_x86_OP(PCMPGTW, 0x65); +MMX_x86_OP(PCMPGTD, 0x66); -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); +MMX_x86_OP(PCMPEQB, 0x74); +MMX_x86_OP(PCMPEQW, 0x75); +MMX_x86_OP(PCMPEQD, 0x76); -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); +MMX_x86_OP(PSRLW, 0xd1); +MMX_x86_OP(PSRLD, 0xd2); +MMX_x86_OP(PSRLQ, 0xd3); +MMX_x86_OP(PSRAW, 0xe1); +MMX_x86_OP(PSRAD, 0xe2); +MMX_x86_OP(PSLLW, 0xf1); +MMX_x86_OP(PSLLD, 0xf2); +MMX_x86_OP(PSLLQ, 0xf3); -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); +MMX_x86_OP(PMULLW, 0xd5); +MMX_x86_OP(PMULHW, 0xe5); MMX_x86_OP(PMADDWD, 0xf5); -static __inline void MMX_PACKSSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x63); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static __inline void MMX_PACKUSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKUSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static __inline void MMX_PACKSSDW(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSDW(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static __inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHBW(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static __inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHWD(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x61); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static __inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHDQ(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x62); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static __inline void MMX_PSRLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static __inline void MMX_PSRAW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static __inline void MMX_PSLLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static __inline void MMX_PSRLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static __inline void MMX_PSRAD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static __inline void MMX_PSLLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static __inline void MMX_PSRLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static __inline void MMX_PSRAQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static __inline void MMX_PSLLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } - -static __inline void SAVE_EA(void) +static __inline void +SAVE_EA(void) { - addbyte(0x89); /*MOV [ESP+0x24], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); + addbyte(0x89); /*MOV [ESP+0x24], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x24); } -static __inline void LOAD_EA(void) +static __inline void +LOAD_EA(void) { - addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x24); + addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x24); } #define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static __inline void MEM_CHECK_WRITE(x86seg *seg) +static __inline void +MEM_CHECK_WRITE(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3 = NULL; + uint8_t *jump1, *jump2, *jump3 = NULL; - CHECK_SEG_WRITE(seg); + CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RCX, writelookup2*/ - addbyte(0xb9); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RCX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf9); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - /*slowpath:*/ - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - - - load_param_1_reg_32(REG_EDI); - load_param_2_32(&codeblock[block_current], 1); - - call(&codeblock[block_current], (uintptr_t)mmutranslatereal32); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - - LOAD_EA(); -} - -static __inline void MEM_CHECK_WRITE_W(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 1[EDI]*/ - addbyte(0x77); - addbyte(0x01); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - addbyte(0x89); /*MOV EBX, EDI*/ - addbyte(0xfb); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RAX, writelookup2*/ - addbyte(0xb8); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf8); - addbyte(-1); - } - addbyte(0x74); /*JE +*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ - addbyte(0x3c); - addbyte(0xf0); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; - jump_pos = block_pos; - load_param_1_reg_32(REG_EBX); - load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal32); - addbyte(0x83); /*ADD EBX, 1*/ - addbyte(0xc3); - addbyte(1); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $fff, EBX*/ - addbyte(0xc3); - addlong(0xfff); - addbyte(0x74); /*JNE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static __inline void MEM_CHECK_WRITE_L(x86seg *seg) -{ - uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; - int jump_pos; - - CHECK_SEG_WRITE(seg); - - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOV ESI, seg->base*/ - addbyte(0x34); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &addr*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ESI, [RSI]*/ - addbyte(0x36); - } - - - /*seg = ESI, addr = EAX*/ - - if (IS_32_ADDR(&cr0)) - { - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&cr0); - addbyte(0); - } - else - { - addbyte(0x48); /*MOV RDI, &cr0*/ - addbyte(0xbf); - addquad((uint64_t)&cr0); - addbyte(0x83); /*CMPL [RDI], 0*/ - addbyte(0x3f); - addbyte(0); - } - addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ - addbyte(0x8d); - addbyte(0x3c); - addbyte(0x30); - addbyte(0x79); /*JNS +*/ - jump1 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } - addbyte(0x8d); /*LEA ESI, 3[EDI]*/ - addbyte(0x77); - addbyte(0x03); - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } - addbyte(0x89); /*MOV EBX, EDI*/ - addbyte(0xfb); - addbyte(0xc1); /*SHR EDI, 12*/ - addbyte(0xef); - addbyte(12); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xee); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x48); /*MOV RAX, writelookup2*/ - addbyte(0xb8); - addquad((uint64_t)writelookup2); - addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ - addbyte(0x3c); - addbyte(0xf8); - addbyte(-1); - } - addbyte(0x74); /*JE slowpath*/ - jump2 = &codeblock[block_current].data[block_pos]; - addbyte(0); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - addbyte(-1); - } - else - { - addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ - addbyte(0x3c); - addbyte(0xf0); - addbyte(-1); - } - addbyte(0x75); /*JNE +*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - - /*slowpath:*/ - *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; - jump_pos = block_pos; - load_param_1_reg_32(REG_EBX); - load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], (uintptr_t)mmutranslatereal32); - addbyte(0x83); /*ADD EBX, 3*/ - addbyte(0xc3); - addbyte(3); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE mem_abrt_rout*/ - addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); - /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ - addbyte(0xf7); /*TEST $ffc, EBX*/ - addbyte(0xc3); - addlong(0xffc); - addbyte(0x74); /*JE slowpath*/ - addbyte(jump_pos - block_pos - 1); - - *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; - - LOAD_EA(); -} - -static __inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ESI, [RSI]*/ + addbyte(0x36); + } + + /*seg = ESI, addr = EAX*/ + + if (IS_32_ADDR(&cr0)) { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &cr0); + addbyte(0); + } else { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t) &cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + addbyte(0x79); /*JNS +*/ + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); + addbyte(0xfe); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ - addbyte(0x04); - addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmembl); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static __inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+4+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t) (uintptr_t) writelookup2); addbyte(-1); + } else { + addbyte(0x48); /*MOV RCX, writelookup2*/ + addbyte(0xb9); + addquad((uint64_t) writelookup2); + addbyte(0x83); /*CMP [RCX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf9); + addbyte(-1); + } + addbyte(0x75); /*JNE +*/ + jump2 = &codeblock[block_current].data[block_pos]; + addbyte(0); + + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + *jump3 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump3 - 1; + /*slowpath:*/ + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + + load_param_1_reg_32(REG_EDI); + load_param_2_32(&codeblock[block_current], 1); + + call(&codeblock[block_current], (uintptr_t) mmutranslatereal32); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong((uintptr_t) &codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t) (&codeblock[block_current].data[block_pos]) + 4)); + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + *jump2 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump2 - 1; + + LOAD_EA(); +} + +static __inline void +MEM_CHECK_WRITE_W(x86seg *seg) +{ + uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; + int jump_pos; + + CHECK_SEG_WRITE(seg); + + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOV ESI, seg->base*/ + addbyte(0x34); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ESI, [RSI]*/ + addbyte(0x36); + } + + /*seg = ESI, addr = EAX*/ + + if (IS_32_ADDR(&cr0)) { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &cr0); + addbyte(0); + } else { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t) &cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + addbyte(0x79); /*JNS +*/ + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } + addbyte(0x8d); /*LEA ESI, 1[EDI]*/ + addbyte(0x77); + addbyte(0x01); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x66); /*MOV AX,[RDI+RSI]*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } + addbyte(0x89); /*MOV EBX, EDI*/ + addbyte(0xfb); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x48); /*MOV RAX, writelookup2*/ + addbyte(0xb8); + addquad((uint64_t) writelookup2); + addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf8); + addbyte(-1); + } + addbyte(0x74); /*JE +*/ + jump2 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ + addbyte(0x3c); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ + addbyte(0x3c); + addbyte(0xf0); + addbyte(-1); + } + addbyte(0x75); /*JNE +*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + + /*slowpath:*/ + *jump2 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump2 - 1; + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + *jump4 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump4 - 1; + jump_pos = block_pos; + load_param_1_reg_32(REG_EBX); + load_param_2_32(&codeblock[block_current], 1); + call(&codeblock[block_current], (uintptr_t) mmutranslatereal32); + addbyte(0x83); /*ADD EBX, 1*/ + addbyte(0xc3); + addbyte(1); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong((uintptr_t) &codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST $fff, EBX*/ + addbyte(0xc3); + addlong(0xfff); + addbyte(0x74); /*JNE slowpath*/ + addbyte(jump_pos - block_pos - 1); + + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + *jump3 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump3 - 1; + + LOAD_EA(); +} + +static __inline void +MEM_CHECK_WRITE_L(x86seg *seg) +{ + uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; + int jump_pos; + + CHECK_SEG_WRITE(seg); + + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOV ESI, seg->base*/ + addbyte(0x34); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &addr*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ESI, [RSI]*/ + addbyte(0x36); + } + + /*seg = ESI, addr = EAX*/ + + if (IS_32_ADDR(&cr0)) { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &cr0); + addbyte(0); + } else { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t) &cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } + addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x8d); + addbyte(0x3c); + addbyte(0x30); + addbyte(0x79); /*JNS +*/ + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } + addbyte(0x8d); /*LEA ESI, 3[EDI]*/ + addbyte(0x77); + addbyte(0x03); + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } + addbyte(0x89); /*MOV EBX, EDI*/ + addbyte(0xfb); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x48); /*MOV RAX, writelookup2*/ + addbyte(0xb8); + addquad((uint64_t) writelookup2); + addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf8); + addbyte(-1); + } + addbyte(0x74); /*JE slowpath*/ + jump2 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ + addbyte(0x3c); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + addbyte(-1); + } else { + addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ + addbyte(0x3c); + addbyte(0xf0); + addbyte(-1); + } + addbyte(0x75); /*JNE +*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + + /*slowpath:*/ + *jump2 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump2 - 1; + if (!(seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) && !(seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + *jump4 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump4 - 1; + jump_pos = block_pos; + load_param_1_reg_32(REG_EBX); + load_param_2_32(&codeblock[block_current], 1); + call(&codeblock[block_current], (uintptr_t) mmutranslatereal32); + addbyte(0x83); /*ADD EBX, 3*/ + addbyte(0xc3); + addbyte(3); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong((uintptr_t) &codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST $ffc, EBX*/ + addbyte(0xc3); + addlong(0xffc); + addbyte(0x74); /*JE slowpath*/ + addbyte(jump_pos - block_pos - 1); + + *jump1 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump1 - 1; + *jump3 = (uintptr_t) &codeblock[block_current].data[block_pos] - (uintptr_t) jump3 - 1; + + LOAD_EA(); +} + +static __inline int +MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); addbyte(0x8b); - addbyte(0x04); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV AL,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmembl); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); + /*done:*/ + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline int +MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ + addbyte(0x8b); + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemwl); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); + /*done:*/ + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline int +MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL ECX, seg->base*/ + addbyte(0x0c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV ECX, [RSI]*/ + addbyte(0x0e); + } + addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x08); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(readlookup2)) { + addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) readlookup2); + } else { + addbyte(0x48); /*MOV RDX, readlookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) readlookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 2); + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ + addbyte(0x04); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xeb); /*JMP done*/ + addbyte(2 + 2 + 12); + /*slowpath:*/ + addbyte(0x01); /*ADD ECX,EAX*/ + addbyte(0xc1); + load_param_1_reg_32(REG_ECX); + call_long((uintptr_t) readmemll); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); + /*done:*/ + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} + +static __inline void +MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +{ + if (host_reg & 0x10) { + /*Handle high byte of register*/ + if (host_reg & 8) { + addbyte(0x45); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } else { + addbyte(0x41); /*MOVL R8, host_reg*/ + addbyte(0x89); + addbyte(0xc0 | ((host_reg & 7) << 3)); + } + addbyte(0x66); /*SHR R8, 8*/ + addbyte(0x41); + addbyte(0xc1); + addbyte(0xe8); + addbyte(8); + host_reg = 8; + } + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL EBX, seg->base*/ + addbyte(0x1c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV EBX, [RSI]*/ + addbyte(0x1e); + } + addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x18); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x88); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemwl); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static __inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL ECX, seg->base*/ - addbyte(0x0c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV ECX, [RSI]*/ - addbyte(0x0e); - } - addbyte(0x67); /*LEA ESI, (EAX,ECX)*/ - addbyte(0x8d); - addbyte(0x34); - addbyte(0x08); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(readlookup2)) - { - addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)readlookup2); - } - else - { - addbyte(0x48); /*MOV RDX, readlookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)readlookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+3+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2); - addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ - addbyte(0x04); + } else { + addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(0xeb); /*JMP done*/ - addbyte(2+2+12); - /*slowpath:*/ - addbyte(0x01); /*ADD ECX,EAX*/ - addbyte(0xc1); - load_param_1_reg_32(REG_ECX); - call_long((uintptr_t)readmemll); - addbyte(0x89); /*MOV ECX, EAX*/ - addbyte(0xc1); - /*done:*/ - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12); + } else { + addbyte(2 + 2 + 2 + 12); + } + /*slowpath:*/ + load_param_2_reg_32(host_reg); + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + load_param_1_reg_32(REG_EBX); + call_long((uintptr_t) writemembl); + /*done:*/ } - -static __inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (host_reg & 0x10) - { - /*Handle high byte of register*/ - if (host_reg & 8) - { - addbyte(0x45); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - else - { - addbyte(0x41); /*MOVL R8, host_reg*/ - addbyte(0x89); - addbyte(0xc0 | ((host_reg & 7) << 3)); - } - addbyte(0x66); /*SHR R8, 8*/ - addbyte(0x41); - addbyte(0xc1); - addbyte(0xe8); - addbyte(8); - host_reg = 8; - } - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL EBX, seg->base*/ + addbyte(0x1c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV EBX, [RSI]*/ + addbyte(0x1e); + } + addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x18); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x88); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x88); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12); - } else { - addbyte(2+2+2+12); - } - /*slowpath:*/ - load_param_2_reg_32(host_reg); - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - load_param_1_reg_32(REG_EBX); - call_long((uintptr_t)writemembl); - /*done:*/ -} -static __inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 1*/ - addbyte(0xc7); - addlong(1); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); - if (host_reg & 8) - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x44); - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12); - } else { - addbyte(2+2+2+12); - } - /*slowpath:*/ - load_param_2_reg_32(host_reg); - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - load_param_1_reg_32(REG_EBX); - call_long((uintptr_t)writememwl); - /*done:*/ + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 5 : 4) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 5 : 4) + 2); + if (host_reg & 8) { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x44); + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12); + } else { + addbyte(2 + 2 + 2 + 12); + } + /*slowpath:*/ + load_param_2_reg_32(host_reg); + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + load_param_1_reg_32(REG_EBX); + call_long((uintptr_t) writememwl); + /*done:*/ } -static __inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) - { - addbyte(0x8b); /*MOVL EBX, seg->base*/ - addbyte(0x1c); - addbyte(0x25); - addlong((uint32_t)(uintptr_t)&seg->base); - } - else - { - addbyte(0x48); /*MOV RSI, &seg->base*/ - addbyte(0xb8 | REG_ESI); - addquad((uint64_t)&seg->base); - addbyte(0x8b); /*MOV EBX, [RSI]*/ - addbyte(0x1e); - } - addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ - addbyte(0x8d); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } else if (IS_32_ADDR(&seg->base)) { + addbyte(0x8b); /*MOVL EBX, seg->base*/ + addbyte(0x1c); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &seg->base); + } else { + addbyte(0x48); /*MOV RSI, &seg->base*/ + addbyte(0xb8 | REG_ESI); + addquad((uint64_t) &seg->base); + addbyte(0x8b); /*MOV EBX, [RSI]*/ + addbyte(0x1e); + } + addbyte(0x67); /*LEA ESI, (EAX,EBX)*/ + addbyte(0x8d); + addbyte(0x34); + addbyte(0x18); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + if (IS_32_ADDR(writelookup2)) { + addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ + addbyte(0x48); + addbyte(0x8b); addbyte(0x34); - addbyte(0x18); - addbyte(0x89); /*MOV EDI, ESI*/ - addbyte(0xf7); - addbyte(0xc1); /*SHR ESI, 12*/ - addbyte(0xe8 | REG_ESI); - addbyte(12); - addbyte(0xf7); /*TEST EDI, 3*/ - addbyte(0xc7); - addlong(3); - if (IS_32_ADDR(writelookup2)) - { - addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ - addbyte(0x48); - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf5); - addlong((uint32_t)(uintptr_t)writelookup2); - } - else - { - addbyte(0x48); /*MOV RDX, writelookup2*/ - addbyte(0xb8 | REG_EDX); - addquad((uint64_t)writelookup2); - addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ - addbyte(0x8b); - addbyte(0x34); - addbyte(0xf2); - } - addbyte(0x75); /*JNE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 4:3)+2); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xf8 | REG_ESI); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 4:3)+2); - if (host_reg & 8) - { - addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x89); - addbyte(0x04 | ((host_reg & 7) << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - else - { - addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(REG_EDI | (REG_ESI << 3)); - } - addbyte(0xeb); /*JMP done*/ - if (host_reg & 8) { - addbyte(2+2+3+12); - } else { - addbyte(2+2+2+12); - } - /*slowpath:*/ - load_param_2_reg_32(host_reg); - addbyte(0x01); /*ADD EBX,EAX*/ - addbyte(0xc3); - load_param_1_reg_32(REG_EBX); - call_long((uintptr_t)writememll); - /*done:*/ + addbyte(0xf5); + addlong((uint32_t) (uintptr_t) writelookup2); + } else { + addbyte(0x48); /*MOV RDX, writelookup2*/ + addbyte(0xb8 | REG_EDX); + addquad((uint64_t) writelookup2); + addbyte(0x48); /*MOV RSI, [RDX+RSI*8]*/ + addbyte(0x8b); + addbyte(0x34); + addbyte(0xf2); + } + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + ((host_reg & 8) ? 4 : 3) + 2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(((host_reg & 8) ? 4 : 3) + 2); + if (host_reg & 8) { + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x89); + addbyte(0x04 | ((host_reg & 7) << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } else { + addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + } + addbyte(0xeb); /*JMP done*/ + if (host_reg & 8) { + addbyte(2 + 2 + 3 + 12); + } else { + addbyte(2 + 2 + 2 + 12); + } + /*slowpath:*/ + load_param_2_reg_32(host_reg); + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + load_param_1_reg_32(REG_EBX); + call_long((uintptr_t) writememll); + /*done:*/ } -static __inline void LOAD_SEG(int host_reg, void *seg) +static __inline void +LOAD_SEG(int host_reg, void *seg) { - load_param_2_64(&codeblock[block_current], (uint64_t)seg); - load_param_1_reg_32(host_reg); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + load_param_2_64(&codeblock[block_current], (uint64_t) seg); + load_param_1_reg_32(host_reg); + CALL_FUNC((uintptr_t) loadseg); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } diff --git a/src/codegen/codegen_ops_x86.h b/src/codegen/codegen_ops_x86.h index 28fa33bd7..80e081220 100644 --- a/src/codegen/codegen_ops_x86.h +++ b/src/codegen/codegen_ops_x86.h @@ -4,35 +4,35 @@ ESI, EDI - work registers EBP - points at emulated register array */ -#define HOST_REG_START 1 -#define HOST_REG_END 4 +#define HOST_REG_START 1 +#define HOST_REG_END 4 #define HOST_REG_XMM_START 0 -#define HOST_REG_XMM_END 7 -static __inline int find_host_reg(void) +#define HOST_REG_XMM_END 7 +static __inline int +find_host_reg(void) { - int c; - for (c = HOST_REG_START; c < HOST_REG_END; c++) - { - if (host_reg_mapping[c] == -1) - break; - } + int c; + for (c = HOST_REG_START; c < HOST_REG_END; c++) { + if (host_reg_mapping[c] == -1) + break; + } - if (c == NR_HOST_REGS) - fatal("Out of host regs!\n"); - return c; + if (c == NR_HOST_REGS) + fatal("Out of host regs!\n"); + return c; } -static __inline int find_host_xmm_reg(void) +static __inline int +find_host_xmm_reg(void) { - int c; - for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) - { - if (host_reg_xmm_mapping[c] == -1) - break; - } + int c; + for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) { + if (host_reg_xmm_mapping[c] == -1) + break; + } - if (c == HOST_REG_XMM_END) - fatal("Out of host XMM regs!\n"); - return c; + if (c == HOST_REG_XMM_END) + fatal("Out of host XMM regs!\n"); + return c; } #if 0 @@ -52,2637 +52,2572 @@ static __inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) addword(val); } #endif -static __inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x45); - addbyte(addr - (uint32_t)&cpu_state - 128); - addlong(val); - } - else - { - addbyte(0xC7); /*MOVL [addr],val*/ - addbyte(0x05); - addlong(addr); - addlong(val); - } -} - -static __inline void STORE_IMM_REG_B(int reg, uint8_t val) -{ - addbyte(0xC6); /*MOVB [addr],val*/ - addbyte(0x45); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - addbyte(val); -} -static __inline void STORE_IMM_REG_W(int reg, uint16_t val) -{ - addbyte(0x66); /*MOVW [addr],val*/ - addbyte(0xC7); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - addword(val); -} -static __inline void STORE_IMM_REG_L(int reg, uint32_t val) +static __inline void +STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) { + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { addbyte(0xC7); /*MOVL [addr],val*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); + addbyte(addr - (uint32_t) &cpu_state - 128); addlong(val); + } else { + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x05); + addlong(addr); + addlong(val); + } } -static __inline int LOAD_REG_B(int reg) +static __inline void +STORE_IMM_REG_B(int reg, uint8_t val) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX B[reg],host_reg*/ - addbyte(0xb6); - addbyte(0x45 | (host_reg << 3)); - if (reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); - - return host_reg; + addbyte(0xC6); /*MOVB [addr],val*/ + addbyte(0x45); + if (reg & 4) + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.l)); + addbyte(val); } -static __inline int LOAD_REG_W(int reg) +static __inline void +STORE_IMM_REG_W(int reg, uint16_t val) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x0f); /*MOVZX W[reg],host_reg*/ - addbyte(0xb7); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); - - return host_reg; + addbyte(0x66); /*MOVW [addr],val*/ + addbyte(0xC7); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].w)); + addword(val); } -static __inline int LOAD_REG_L(int reg) +static __inline void +STORE_IMM_REG_L(int reg, uint32_t val) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = reg; - - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); - - return host_reg; + addbyte(0xC7); /*MOVL [addr],val*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].l)); + addlong(val); } -static __inline int LOAD_VAR_W(uintptr_t addr) +static __inline int +LOAD_REG_B(int reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = reg; - addbyte(0x66); /*MOVL host_reg,[reg]*/ - addbyte(0x8b); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); + addbyte(0x0f); /*MOVZX B[reg],host_reg*/ + addbyte(0xb6); + addbyte(0x45 | (host_reg << 3)); + if (reg & 4) + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[reg & 3].b.l)); - return host_reg; + return host_reg; } -static __inline int LOAD_VAR_WL(uintptr_t addr) +static __inline int +LOAD_REG_W(int reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = reg; - addbyte(0x0f); /*MOVZX host_reg, [addr]*/ - addbyte(0xb7); - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); + addbyte(0x0f); /*MOVZX W[reg],host_reg*/ + addbyte(0xb7); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].w)); - return host_reg; + return host_reg; } -static __inline int LOAD_VAR_L(uintptr_t addr) +static __inline int +LOAD_REG_L(int reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = reg; - addbyte(0x8b); /*MOVL host_reg,[reg]*/ - addbyte(0x05 | (host_reg << 3)); - addlong((uint32_t)addr); + addbyte(0x8b); /*MOVL host_reg,[reg]*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[reg & 7].l)); - return host_reg; + return host_reg; } -static __inline int LOAD_REG_IMM(uint32_t imm) +static __inline int +LOAD_VAR_W(uintptr_t addr) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; - addbyte(0xc7); /*MOVL host_reg, imm*/ - addbyte(0xc0 | host_reg); - addlong(imm); + addbyte(0x66); /*MOVL host_reg,[reg]*/ + addbyte(0x8b); + addbyte(0x05 | (host_reg << 3)); + addlong((uint32_t) addr); - return host_reg; + return host_reg; +} +static __inline int +LOAD_VAR_WL(uintptr_t addr) +{ + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; + + addbyte(0x0f); /*MOVZX host_reg, [addr]*/ + addbyte(0xb7); + addbyte(0x05 | (host_reg << 3)); + addlong((uint32_t) addr); + + return host_reg; +} +static __inline int +LOAD_VAR_L(uintptr_t addr) +{ + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; + + addbyte(0x8b); /*MOVL host_reg,[reg]*/ + addbyte(0x05 | (host_reg << 3)); + addlong((uint32_t) addr); + + return host_reg; } -static __inline int LOAD_HOST_REG(int host_reg) +static __inline int +LOAD_REG_IMM(uint32_t imm) { - int new_host_reg = find_host_reg(); - host_reg_mapping[new_host_reg] = 0; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 0; - addbyte(0x89); /*MOV new_host_reg, host_reg*/ - addbyte(0xc0 | (host_reg << 3) | new_host_reg); + addbyte(0xc7); /*MOVL host_reg, imm*/ + addbyte(0xc0 | host_reg); + addlong(imm); - return new_host_reg; + return host_reg; } -static __inline void STORE_REG_B_RELEASE(int host_reg) +static __inline int +LOAD_HOST_REG(int host_reg) { - addbyte(0x88); /*MOVB [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - if (host_reg_mapping[host_reg] & 4) - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); - host_reg_mapping[host_reg] = -1; + int new_host_reg = find_host_reg(); + host_reg_mapping[new_host_reg] = 0; + + addbyte(0x89); /*MOV new_host_reg, host_reg*/ + addbyte(0xc0 | (host_reg << 3) | new_host_reg); + + return new_host_reg; } -static __inline void STORE_REG_W_RELEASE(int host_reg) + +static __inline void +STORE_REG_B_RELEASE(int host_reg) { - addbyte(0x66); /*MOVW [reg],host_reg*/ + addbyte(0x88); /*MOVB [reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + if (host_reg_mapping[host_reg] & 4) + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_W_RELEASE(int host_reg) +{ + addbyte(0x66); /*MOVW [reg],host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_L_RELEASE(int host_reg) +{ + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); + host_reg_mapping[host_reg] = -1; +} + +static __inline void +STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) +{ + addbyte(0x88); /*MOVB [guest_reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + if (guest_reg & 4) + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 3].b.h)); + else + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 3].b.l)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) +{ + addbyte(0x66); /*MOVW [guest_reg],host_reg*/ + addbyte(0x89); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 7].w)); + host_reg_mapping[host_reg] = -1; +} +static __inline void +STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) +{ + addbyte(0x89); /*MOVL [guest_reg],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(regs[guest_reg & 7].l)); + host_reg_mapping[host_reg] = -1; +} + +static __inline void +RELEASE_REG(int host_reg) +{ + host_reg_mapping[host_reg] = -1; +} + +static __inline void +STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +{ + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x66); /*MOVW [addr],host_reg*/ addbyte(0x89); addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); - host_reg_mapping[host_reg] = -1; + addbyte((uint32_t) addr - (uint32_t) &cpu_state - 128); + } else { + addbyte(0x66); /*MOVL [reg],host_reg*/ + addbyte(0x89); + addbyte(0x05 | (host_reg << 3)); + addlong(addr); + } } -static __inline void STORE_REG_L_RELEASE(int host_reg) +static __inline void +STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) { + if (addr >= (uintptr_t) &cpu_state && addr < ((uintptr_t) &cpu_state) + 0x100) { + addbyte(0x89); /*MOVL [addr],host_reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint32_t) addr - (uint32_t) &cpu_state - 128); + } else { addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); - host_reg_mapping[host_reg] = -1; -} - -static __inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x88); /*MOVB [guest_reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - if (guest_reg & 4) - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.h)); - else - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.l)); - host_reg_mapping[host_reg] = -1; -} -static __inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x66); /*MOVW [guest_reg],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].w)); - host_reg_mapping[host_reg] = -1; -} -static __inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) -{ - addbyte(0x89); /*MOVL [guest_reg],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].l)); - host_reg_mapping[host_reg] = -1; -} - -static __inline void RELEASE_REG(int host_reg) -{ - host_reg_mapping[host_reg] = -1; -} - -static __inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x66); /*MOVW [addr],host_reg*/ - addbyte(0x89); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x66); /*MOVL [reg],host_reg*/ - addbyte(0x89); - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } -} -static __inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) -{ - if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) - { - addbyte(0x89); /*MOVL [addr],host_reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); - } - else - { - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x05 | (host_reg << 3)); - addlong(addr); - } + addbyte(0x05 | (host_reg << 3)); + addlong(addr); + } } #define STORE_HOST_REG_ADDR_BL STORE_HOST_REG_ADDR #define STORE_HOST_REG_ADDR_WL STORE_HOST_REG_ADDR -static __inline void ADD_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_B(int dst_reg, int src_reg) { - addbyte(0x00); /*ADDB dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x00); /*ADDB dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void ADD_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_W(int dst_reg, int src_reg) { - addbyte(0x66); /*ADDW dst_reg, src_reg*/ - addbyte(0x01); - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x66); /*ADDW dst_reg, src_reg*/ + addbyte(0x01); + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void ADD_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +ADD_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x01); /*ADDL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x01); /*ADDL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline void +ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - addbyte(0x80); /*ADDB host_reg, imm*/ + addbyte(0x80); /*ADDB host_reg, imm*/ + addbyte(0xC0 | host_reg); + addbyte(imm); +} +static __inline void +ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + if (imm < 0x80 || imm >= 0xff80) { + addbyte(0x66); /*ADDW host_reg, imm*/ + addbyte(0x83); addbyte(0xC0 | host_reg); - addbyte(imm); + addbyte(imm & 0xff); + } else { + addbyte(0x66); /*ADDW host_reg, imm*/ + addbyte(0x81); + addbyte(0xC0 | host_reg); + addword(imm); + } } -static __inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline void +ADD_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x83); - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*ADDW host_reg, imm*/ - addbyte(0x81); - addbyte(0xC0 | host_reg); - addword(imm); - } -} -static __inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ADDL host_reg, imm*/ - addbyte(0xC0 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*ADDL host_reg, imm*/ + addbyte(0xC0 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*ADDL host_reg, imm*/ + addbyte(0xC0 | host_reg); + addlong(imm); + } } #define AND_HOST_REG_B AND_HOST_REG_L #define AND_HOST_REG_W AND_HOST_REG_L -static __inline void AND_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +AND_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x21); /*ANDL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x21); /*ANDL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +AND_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ANDL host_reg, imm*/ - addbyte(0xE0 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*ANDL host_reg, imm*/ + addbyte(0xE0 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*ANDL host_reg, imm*/ + addbyte(0xE0 | host_reg); + addlong(imm); + } } -static __inline int TEST_HOST_REG_B(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_B(int dst_reg, int src_reg) { - AND_HOST_REG_B(dst_reg, src_reg); + AND_HOST_REG_B(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static __inline int TEST_HOST_REG_W(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_W(int dst_reg, int src_reg) { - AND_HOST_REG_W(dst_reg, src_reg); + AND_HOST_REG_W(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static __inline int TEST_HOST_REG_L(int dst_reg, int src_reg) +static __inline int +TEST_HOST_REG_L(int dst_reg, int src_reg) { - AND_HOST_REG_L(dst_reg, src_reg); + AND_HOST_REG_L(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static __inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline int +TEST_HOST_REG_IMM(int host_reg, uint32_t imm) { - AND_HOST_REG_IMM(host_reg, imm); + AND_HOST_REG_IMM(host_reg, imm); - return host_reg; + return host_reg; } #define OR_HOST_REG_B OR_HOST_REG_L #define OR_HOST_REG_W OR_HOST_REG_L -static __inline void OR_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +OR_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x09); /*ORL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x09); /*ORL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +OR_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*ORL host_reg, imm*/ - addbyte(0xC8 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*ORL host_reg, imm*/ + addbyte(0xC8 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*ORL host_reg, imm*/ + addbyte(0xC8 | host_reg); + addlong(imm); + } } -static __inline void NEG_HOST_REG_B(int reg) +static __inline void +NEG_HOST_REG_B(int reg) { - addbyte(0xf6); - addbyte(0xd8 | reg); + addbyte(0xf6); + addbyte(0xd8 | reg); } -static __inline void NEG_HOST_REG_W(int reg) +static __inline void +NEG_HOST_REG_W(int reg) { - addbyte(0x66); - addbyte(0xf7); - addbyte(0xd8 | reg); + addbyte(0x66); + addbyte(0xf7); + addbyte(0xd8 | reg); } -static __inline void NEG_HOST_REG_L(int reg) +static __inline void +NEG_HOST_REG_L(int reg) { - addbyte(0xf7); - addbyte(0xd8 | reg); + addbyte(0xf7); + addbyte(0xd8 | reg); } -static __inline void SUB_HOST_REG_B(int dst_reg, int src_reg) +static __inline void +SUB_HOST_REG_B(int dst_reg, int src_reg) { - addbyte(0x28); /*SUBB dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x28); /*SUBB dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void SUB_HOST_REG_W(int dst_reg, int src_reg) +static __inline void +SUB_HOST_REG_W(int dst_reg, int src_reg) { - addbyte(0x66); /*SUBW dst_reg, src_reg*/ - addbyte(0x29); - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x66); /*SUBW dst_reg, src_reg*/ + addbyte(0x29); + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void SUB_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +SUB_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x29); /*SUBL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x29); /*SUBL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline void +SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - addbyte(0x80); /*SUBB host_reg, imm*/ + addbyte(0x80); /*SUBB host_reg, imm*/ + addbyte(0xE8 | host_reg); + addbyte(imm); +} +static __inline void +SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +{ + if (imm < 0x80 || imm >= 0xff80) { + addbyte(0x66); /*SUBW host_reg, imm*/ + addbyte(0x83); + addbyte(0xE8 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x66); /*SUBW host_reg, imm*/ + addbyte(0x81); + addbyte(0xE8 | host_reg); + addword(imm); + } +} +static __inline void +SUB_HOST_REG_IMM(int host_reg, uint32_t imm) +{ + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*SUBL host_reg, imm*/ addbyte(0xE8 | host_reg); addbyte(imm); -} -static __inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) -{ - if (imm < 0x80 || imm >= 0xff80) - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x83); - addbyte(0xE8 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x66); /*SUBW host_reg, imm*/ - addbyte(0x81); - addbyte(0xE8 | host_reg); - addword(imm); - } -} -static __inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) -{ - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addbyte(imm); - } - else - { - addbyte(0x81); /*SUBL host_reg, imm*/ - addbyte(0xE8 | host_reg); - addlong(imm); - } + } else { + addbyte(0x81); /*SUBL host_reg, imm*/ + addbyte(0xE8 | host_reg); + addlong(imm); + } } -static __inline void INC_HOST_REG_W(int host_reg) +static __inline void +INC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*INCW host_reg*/ - addbyte(0x40 | host_reg); + addbyte(0x66); /*INCW host_reg*/ + addbyte(0x40 | host_reg); } -static __inline void INC_HOST_REG(int host_reg) +static __inline void +INC_HOST_REG(int host_reg) { - addbyte(0x40 | host_reg); /*DECL host_reg*/ + addbyte(0x40 | host_reg); /*DECL host_reg*/ } -static __inline void DEC_HOST_REG_W(int host_reg) +static __inline void +DEC_HOST_REG_W(int host_reg) { - addbyte(0x66); /*DECW host_reg*/ - addbyte(0x48 | host_reg); + addbyte(0x66); /*DECW host_reg*/ + addbyte(0x48 | host_reg); } -static __inline void DEC_HOST_REG(int host_reg) +static __inline void +DEC_HOST_REG(int host_reg) { - addbyte(0x48 | host_reg); /*DECL host_reg*/ + addbyte(0x48 | host_reg); /*DECL host_reg*/ } -static __inline int CMP_HOST_REG_B(int dst_reg, int src_reg) +static __inline int +CMP_HOST_REG_B(int dst_reg, int src_reg) { - SUB_HOST_REG_B(dst_reg, src_reg); + SUB_HOST_REG_B(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static __inline int CMP_HOST_REG_W(int dst_reg, int src_reg) +static __inline int +CMP_HOST_REG_W(int dst_reg, int src_reg) { - SUB_HOST_REG_W(dst_reg, src_reg); + SUB_HOST_REG_W(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static __inline int CMP_HOST_REG_L(int dst_reg, int src_reg) +static __inline int +CMP_HOST_REG_L(int dst_reg, int src_reg) { - SUB_HOST_REG_L(dst_reg, src_reg); + SUB_HOST_REG_L(dst_reg, src_reg); - return dst_reg; + return dst_reg; } -static __inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static __inline int +CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { - SUB_HOST_REG_IMM_B(host_reg, imm); + SUB_HOST_REG_IMM_B(host_reg, imm); - return host_reg; + return host_reg; } -static __inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static __inline int +CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) { - SUB_HOST_REG_IMM_W(host_reg, imm); + SUB_HOST_REG_IMM_W(host_reg, imm); - return host_reg; + return host_reg; } -static __inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) +static __inline int +CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) { - SUB_HOST_REG_IMM(host_reg, imm); + SUB_HOST_REG_IMM(host_reg, imm); - return host_reg; + return host_reg; } #define XOR_HOST_REG_B XOR_HOST_REG_L #define XOR_HOST_REG_W XOR_HOST_REG_L -static __inline void XOR_HOST_REG_L(int dst_reg, int src_reg) +static __inline void +XOR_HOST_REG_L(int dst_reg, int src_reg) { - addbyte(0x31); /*XORL dst_reg, src_reg*/ - addbyte(0xc0 | dst_reg | (src_reg << 3)); + addbyte(0x31); /*XORL dst_reg, src_reg*/ + addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static __inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +static __inline void +XOR_HOST_REG_IMM(int host_reg, uint32_t imm) { - if (imm < 0x80 || imm >= 0xffffff80) - { - addbyte(0x83); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addbyte(imm & 0xff); - } - else - { - addbyte(0x81); /*XORL host_reg, imm*/ - addbyte(0xF0 | host_reg); - addlong(imm); - } + if (imm < 0x80 || imm >= 0xffffff80) { + addbyte(0x83); /*XORL host_reg, imm*/ + addbyte(0xF0 | host_reg); + addbyte(imm & 0xff); + } else { + addbyte(0x81); /*XORL host_reg, imm*/ + addbyte(0xF0 | host_reg); + addlong(imm); + } } -static __inline void CALL_FUNC(uintptr_t dest) +static __inline void +CALL_FUNC(uintptr_t dest) { - addbyte(0xE8); /*CALL*/ - addlong(((uintptr_t)dest - (uintptr_t)(&codeblock[block_current].data[block_pos + 4]))); + addbyte(0xE8); /*CALL*/ + addlong(((uintptr_t) dest - (uintptr_t) (&codeblock[block_current].data[block_pos + 4]))); } -static __inline void SHL_B_IMM(int reg, int count) +static __inline void +SHL_B_IMM(int reg, int count) { - addbyte(0xc0); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); + addbyte(0xc0); /*SHL reg, count*/ + addbyte(0xc0 | reg | 0x20); + addbyte(count); } -static __inline void SHL_W_IMM(int reg, int count) +static __inline void +SHL_W_IMM(int reg, int count) { - addbyte(0x66); /*SHL reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x20); - addbyte(count); + addbyte(0x66); /*SHL reg, count*/ + addbyte(0xc1); + addbyte(0xc0 | reg | 0x20); + addbyte(count); } -static __inline void SHL_L_IMM(int reg, int count) +static __inline void +SHL_L_IMM(int reg, int count) { - addbyte(0xc1); /*SHL reg, count*/ - addbyte(0xc0 | reg | 0x20); - addbyte(count); + addbyte(0xc1); /*SHL reg, count*/ + addbyte(0xc0 | reg | 0x20); + addbyte(count); } -static __inline void SHR_B_IMM(int reg, int count) +static __inline void +SHR_B_IMM(int reg, int count) { - addbyte(0xc0); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); + addbyte(0xc0); /*SHR reg, count*/ + addbyte(0xc0 | reg | 0x28); + addbyte(count); } -static __inline void SHR_W_IMM(int reg, int count) +static __inline void +SHR_W_IMM(int reg, int count) { - addbyte(0x66); /*SHR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x28); - addbyte(count); + addbyte(0x66); /*SHR reg, count*/ + addbyte(0xc1); + addbyte(0xc0 | reg | 0x28); + addbyte(count); } -static __inline void SHR_L_IMM(int reg, int count) +static __inline void +SHR_L_IMM(int reg, int count) { - addbyte(0xc1); /*SHR reg, count*/ - addbyte(0xc0 | reg | 0x28); - addbyte(count); + addbyte(0xc1); /*SHR reg, count*/ + addbyte(0xc0 | reg | 0x28); + addbyte(count); } -static __inline void SAR_B_IMM(int reg, int count) +static __inline void +SAR_B_IMM(int reg, int count) { - addbyte(0xc0); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); + addbyte(0xc0); /*SAR reg, count*/ + addbyte(0xc0 | reg | 0x38); + addbyte(count); } -static __inline void SAR_W_IMM(int reg, int count) +static __inline void +SAR_W_IMM(int reg, int count) { - addbyte(0x66); /*SAR reg, count*/ - addbyte(0xc1); - addbyte(0xc0 | reg | 0x38); - addbyte(count); + addbyte(0x66); /*SAR reg, count*/ + addbyte(0xc1); + addbyte(0xc0 | reg | 0x38); + addbyte(count); } -static __inline void SAR_L_IMM(int reg, int count) +static __inline void +SAR_L_IMM(int reg, int count) { - addbyte(0xc1); /*SAR reg, count*/ - addbyte(0xc0 | reg | 0x38); - addbyte(count); + addbyte(0xc1); /*SAR reg, count*/ + addbyte(0xc0 | reg | 0x38); + addbyte(count); } - -static __inline void CHECK_SEG_READ(x86seg *seg) +static __inline void +CHECK_SEG_READ(x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x05 | 0x38); + addlong((uint32_t) &seg->base); + addbyte(-1); + addbyte(0x0f); + addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - seg->checked = 1; + seg->checked = 1; } -static __inline void CHECK_SEG_WRITE(x86seg *seg) +static __inline void +CHECK_SEG_WRITE(x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - addbyte(0x83); /*CMP seg->base, -1*/ - addbyte(0x05|0x38); - addlong((uint32_t)&seg->base); - addbyte(-1); - addbyte(0x0f); - addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*CMP seg->base, -1*/ + addbyte(0x05 | 0x38); + addlong((uint32_t) &seg->base); + addbyte(-1); + addbyte(0x0f); + addbyte(0x84); /*JE BLOCK_GPF_OFFSET*/ + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - seg->checked = 1; + seg->checked = 1; } -static __inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) +static __inline void +CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_low); - addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ - addbyte(0x82); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - if (end_offset) - { - addbyte(0x83); /*ADD EAX, end_offset*/ - addbyte(0xc0); - addbyte(end_offset); - addbyte(0x3b); /*CMP EAX, seg->limit_high*/ - addbyte(0x05); - addlong((uint32_t)&seg->limit_high); - addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ - addbyte(0x87); - addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); - addbyte(0x83); /*SUB EAX, end_offset*/ - addbyte(0xe8); - addbyte(end_offset); - } -} - -static __inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ - addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static __inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ - addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static __inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static __inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0x83); /*ADD EAX, offset*/ + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ + addbyte(0x05); + addlong((uint32_t) &seg->limit_low); + addbyte(0x0f); /*JB BLOCK_GPF_OFFSET*/ + addbyte(0x82); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + if (end_offset) { + addbyte(0x83); /*ADD EAX, end_offset*/ addbyte(0xc0); - addbyte(offset); - addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ - addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[0] = 8; -} -static __inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ - addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; -} -static __inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ - addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - - host_reg_mapping[0] = 8; -} -static __inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ - addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - - host_reg_mapping[REG_ECX] = 8; - - return REG_ECX; + addbyte(end_offset); + addbyte(0x3b); /*CMP EAX, seg->limit_high*/ + addbyte(0x05); + addlong((uint32_t) &seg->limit_high); + addbyte(0x0f); /*JNBE BLOCK_GPF_OFFSET*/ + addbyte(0x87); + addlong(BLOCK_GPF_OFFSET - (block_pos + 4)); + addbyte(0x83); /*SUB EAX, end_offset*/ + addbyte(0xe8); + addbyte(end_offset); + } } -static __inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) +static __inline void +MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ - addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ + addlong(mem_load_addr_ea_b - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); - host_reg_mapping[0] = 8; + host_reg_mapping[0] = 8; +} +static __inline int +MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ + addlong(mem_load_addr_ea_b_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline void +MEM_LOAD_ADDR_EA_W(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ + addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; +} +static __inline void +MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0x83); /*ADD EAX, offset*/ + addbyte(0xc0); + addbyte(offset); + addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ + addlong(mem_load_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; +} +static __inline int +MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ + addlong(mem_load_addr_ea_w_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; +} +static __inline void +MEM_LOAD_ADDR_EA_L(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ + addlong(mem_load_addr_ea_l - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; +} +static __inline int +MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ + addlong(mem_load_addr_ea_l_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[REG_ECX] = 8; + + return REG_ECX; } -static __inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +static __inline void +MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_B(seg); -} -static __inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_W(seg); -} -static __inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) -{ - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_LOAD_ADDR_EA_L(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } else { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ + addlong(mem_load_addr_ea_q - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + + host_reg_mapping[0] = 8; } -static __inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) +static __inline void +MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ - addlong(mem_store_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_B(seg); } -static __inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +static __inline void +MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_b_no_abrt*/ - addlong(mem_store_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_W(seg); } -static __inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) +static __inline void +MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ - addlong(mem_store_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static __inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_w_no_abrt*/ - addlong(mem_store_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static __inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ - addlong(mem_store_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static __inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) -{ - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - if (host_reg != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg*/ - addbyte(0xc0 | REG_ECX | (host_reg << 3)); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_l_no_abrt*/ - addlong(mem_store_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -} -static __inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) -{ - if (host_reg != REG_EBX) - { - addbyte(0x89); /*MOV EBX, host_reg*/ - addbyte(0xc0 | REG_EBX | (host_reg << 3)); - } - if (host_reg2 != REG_ECX) - { - addbyte(0x89); /*MOV ECX, host_reg2*/ - addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); - } - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ - addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_LOAD_ADDR_EA_L(seg); } -static __inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_B(seg, host_reg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ + addlong(mem_store_addr_ea_b - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); } -static __inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_L(seg, host_reg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_b_no_abrt*/ + addlong(mem_store_addr_ea_b_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); } -static __inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +static __inline void +MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0xb8); /*MOV EAX, addr*/ - addlong(addr); - MEM_STORE_ADDR_EA_W(seg, host_reg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ + addlong(mem_store_addr_ea_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_w_no_abrt*/ + addlong(mem_store_addr_ea_w_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ + addlong(mem_store_addr_ea_l - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) +{ + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + if (host_reg != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg*/ + addbyte(0xc0 | REG_ECX | (host_reg << 3)); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_l_no_abrt*/ + addlong(mem_store_addr_ea_l_no_abrt - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +} +static __inline void +MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +{ + if (host_reg != REG_EBX) { + addbyte(0x89); /*MOV EBX, host_reg*/ + addbyte(0xc0 | REG_EBX | (host_reg << 3)); + } + if (host_reg2 != REG_ECX) { + addbyte(0x89); /*MOV ECX, host_reg2*/ + addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); + } + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ + addlong(mem_store_addr_ea_q - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); } - -static __inline x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +static __inline void +MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) { - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; - if (!mod && rm == 6) - { + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_B(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_L(seg, host_reg); +} +static __inline void +MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +{ + addbyte(0xb8); /*MOV EAX, addr*/ + addlong(addr); + MEM_STORE_ADDR_EA_W(seg, host_reg); +} + +static __inline x86seg * +FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; + if (!mod && rm == 6) { + addbyte(0xb8); /*MOVL EAX, imm16*/ + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + switch (mod) { + case 0: + addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ + addlong((uint32_t) mod1add[0][rm]); + if (mod1add[1][rm] != &zero) { + addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][rm]); + } + break; + case 1: + addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ + addlong((uint32_t) mod1add[0][rm]); + addbyte(0x83); /*ADDL EAX, imm8*/ + addbyte(0xc0 | REG_EAX); + addbyte((int8_t) (rmdat >> 8)); + if (mod1add[1][rm] != &zero) { + addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][rm]); + } + (*op_pc)++; + break; + case 2: addbyte(0xb8); /*MOVL EAX, imm16*/ addlong((fetchdat >> 8) & 0xffff); + addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[0][rm]); + if (mod1add[1][rm] != &zero) { + addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][rm]); + } (*op_pc) += 2; + break; } - else - { - switch (mod) - { - case 0: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - break; - case 1: - addbyte(0xa1); /*MOVL EAX, *mod1add[0][rm]*/ - addlong((uint32_t)mod1add[0][rm]); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 8)); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff); - addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][rm]); - if (mod1add[1][rm] != &zero) - { - addbyte(0x03); /*ADDL EAX, *mod1add[1][rm]*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][rm]); - } - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL EAX, 0xffff*/ - addlong(0xffff); + addbyte(0x25); /*ANDL EAX, 0xffff*/ + addlong(0xffff); - if (mod1seg[rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; + if (mod1seg[rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; } -static __inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +static __inline x86seg * +FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { - uint32_t new_eaaddr; - int mod = (fetchdat >> 6) & 3; - int rm = fetchdat & 7; + uint32_t new_eaaddr; + int mod = (fetchdat >> 6) & 3; + int rm = fetchdat & 7; - if (rm == 4) - { - uint8_t sib = fetchdat >> 8; + if (rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; + + switch (mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, imm32*/ + addlong(new_eaaddr); + (*op_pc) += 4; + } else { + addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + } + break; + case 1: + addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + addbyte(0x83); /*ADDL EAX, imm8*/ + addbyte(0xc0 | REG_EAX); + addbyte((int8_t) (rmdat >> 16)); (*op_pc)++; - - switch (mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - addbyte(0x83); /*ADDL EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(rmdat >> 16)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ - { - if (stack_offset < 0x80 || stack_offset >= 0xffffff80) - { - addbyte(0x83); - addbyte(0xc0 | REG_EAX); - addbyte(stack_offset); - } - else - { - addbyte(0x05); /*ADDL EAX, stack_offset*/ - addlong(stack_offset); - } - } - if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - case 2: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ - addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(2); /*SHL EDI, 2*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - case 3: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ - addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(3); /*SHL EDI, 3*/ - addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ - break; - } - } - } - else - { - if (!mod && rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[rm].l)); - cpu_state.eaaddr = cpu_state.regs[rm].l; - if (mod) - { - if (rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (mod == 1) - { - addbyte(0x83); /*ADD EAX, imm8*/ - addbyte(0xc0 | REG_EAX); - addbyte((int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); /*ADD EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - } - return op_ea_seg; -} - -static __inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) -{ - if (op_32 & 0x200) - return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); - return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); -} - - -static __inline void LOAD_STACK_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[ESP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static __inline void LOAD_EBP_TO_EA(int off) -{ - if (stack32) - { - addbyte(0x8b); /*MOVL EAX,[EBP]*/ - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); - if (off) - { - addbyte(0x83); /*ADD EAX, off*/ - addbyte(0xc0 | (0 << 3) | REG_EAX); - addbyte(off); - } - } - else - { - addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ - addbyte(0xb7); - addbyte(0x45 | (REG_EAX << 3)); - addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].w)); - if (off) - { - addbyte(0x66); /*ADD AX, off*/ - addbyte(0x05); - addword(off); - } - } -} - -static __inline void SP_MODIFY(int off) -{ - if (stack32) - { - if (off < 0x80) - { - addbyte(0x83); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addbyte(off); - } - else - { - addbyte(0x81); /*ADD [ESP], off*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); - addlong(off); - } - } - else - { - if (off < 0x80) - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x83); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addbyte(off); - } - else - { - addbyte(0x66); /*ADD [SP], off*/ - addbyte(0x81); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); - addword(off); - } - } -} - - -static __inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - addbyte(0x83); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static __inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x75); /*JNZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static __inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x66); /*CMPW host_reg, 0*/ - addbyte(0x83); - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} -static __inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) -{ - addbyte(0x83); /*CMPW host_reg, 0*/ - addbyte(0xc0 | 0x38 | host_reg); - addbyte(0); - addbyte(0x74); /*JZ +*/ - addbyte(7+5+(taken_cycles ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(new_pc); - if (taken_cycles) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(taken_cycles); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); -} - -static __inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) -{ - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, new_eaaddr*/ + addlong(new_eaaddr); + addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x76); /*JBE*/ - else - addbyte(0x77); /*JNBE*/ + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + (*op_pc) += 4; break; + } + if (stack_offset && (sib & 7) == 4 && (mod || (sib & 7) != 5)) /*ESP*/ + { + if (stack_offset < 0x80 || stack_offset >= 0xffffff80) { + addbyte(0x83); + addbyte(0xc0 | REG_EAX); + addbyte(stack_offset); + } else { + addbyte(0x05); /*ADDL EAX, stack_offset*/ + addlong(stack_offset); + } + } + if (((sib & 7) == 4 || (mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); + break; + case 1: + addbyte(0x8B); + addbyte(0x45 | (REG_EDI << 3)); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + break; + case 2: + addbyte(0x8B); + addbyte(0x45 | (REG_EDI << 3)); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ + addbyte(0xC1); + addbyte(0xE0 | REG_EDI); + addbyte(2); /*SHL EDI, 2*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + break; + case 3: + addbyte(0x8B); + addbyte(0x45 | (REG_EDI << 3)); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ + addbyte(0xC1); + addbyte(0xE0 | REG_EDI); + addbyte(3); /*SHL EDI, 3*/ + addbyte(0x01); + addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ + break; + } + } + } else { + if (!mod && rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL EAX, imm32*/ + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[rm].l)); + cpu_state.eaaddr = cpu_state.regs[rm].l; + if (mod) { + if (rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (mod == 1) { + addbyte(0x83); /*ADD EAX, imm8*/ + addbyte(0xc0 | REG_EAX); + addbyte((int8_t) (fetchdat >> 8)); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x05); /*ADD EAX, imm32*/ + addlong(new_eaaddr); + (*op_pc) += 4; + } + } + } + return op_ea_seg; +} - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+2); - CALL_FUNC((uintptr_t)CF_SET); +static __inline x86seg * +FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +{ + if (op_32 & 0x200) + return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); + return FETCH_EA_16(op_ea_seg, fetchdat, op_ssegs, op_pc); +} + +static __inline void +LOAD_STACK_TO_EA(int off) +{ + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[ESP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); + } + } else { + addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ + addbyte(0xb7); + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); + } + } +} + +static __inline void +LOAD_EBP_TO_EA(int off) +{ + if (stack32) { + addbyte(0x8b); /*MOVL EAX,[EBP]*/ + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_EBP].l)); + if (off) { + addbyte(0x83); /*ADD EAX, off*/ + addbyte(0xc0 | (0 << 3) | REG_EAX); + addbyte(off); + } + } else { + addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ + addbyte(0xb7); + addbyte(0x45 | (REG_EAX << 3)); + addbyte((uint8_t) cpu_state_offset(regs[REG_EBP].w)); + if (off) { + addbyte(0x66); /*ADD AX, off*/ + addbyte(0x05); + addword(off); + } + } +} + +static __inline void +SP_MODIFY(int off) +{ + if (stack32) { + if (off < 0x80) { + addbyte(0x83); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addbyte(off); + } else { + addbyte(0x81); /*ADD [ESP], off*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].l)); + addlong(off); + } + } else { + if (off < 0x80) { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x83); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addbyte(off); + } else { + addbyte(0x66); /*ADD [SP], off*/ + addbyte(0x81); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[REG_ESP].w)); + addword(off); + } + } +} + +static __inline void +TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x66); /*CMPW host_reg, 0*/ + addbyte(0x83); + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} +static __inline void +TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x75); /*JNZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x66); /*CMPW host_reg, 0*/ + addbyte(0x83); + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} +static __inline void +TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +{ + addbyte(0x83); /*CMPW host_reg, 0*/ + addbyte(0xc0 | 0x38 | host_reg); + addbyte(0); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 5 + (taken_cycles ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(new_pc); + if (taken_cycles) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(taken_cycles); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); +} + +static __inline void +BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) +{ + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + addbyte(0x8a); /*MOV AL, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3a); /*CMP AL, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x76); /*JBE*/ + else + addbyte(0x77); /*JNBE*/ + break; + case FLAGS_SUB16: + addbyte(0x66); /*MOV AX, flags_op1*/ + addbyte(0x8b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x66); /*CMP AX, flags_op2*/ + addbyte(0x3b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x76); /*JBE*/ + else + addbyte(0x77); /*JNBE*/ + break; + case FLAGS_SUB32: + addbyte(0x8b); /*MOV EAX, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3b); /*CMP EAX, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x76); /*JBE*/ + else + addbyte(0x77); /*JNBE*/ + break; + + default: + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + } else { + CALL_FUNC((uintptr_t) ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x75); /*JNZ +*/ + } + if (not ) + addbyte(5 + 2 + 2 + 7 + 5 + (timing_bt ? 4 : 0)); + else + addbyte(5 + 2 + 2); + CALL_FUNC((uintptr_t) CF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + break; + } + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static __inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static __inline void +BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7c); /*JL*/ - else - addbyte(0x7d); /*JNL*/ - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + addbyte(0x8a); /*MOV AL, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3a); /*CMP AL, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7c); /*JL*/ + else + addbyte(0x7d); /*JNL*/ + break; + case FLAGS_SUB16: + addbyte(0x66); /*MOV AX, flags_op1*/ + addbyte(0x8b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x66); /*CMP AX, flags_op2*/ + addbyte(0x3b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7c); /*JL*/ + else + addbyte(0x7d); /*JNL*/ + break; + case FLAGS_SUB32: + addbyte(0x8b); /*MOV EAX, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3b); /*CMP EAX, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7c); /*JL*/ + else + addbyte(0x7d); /*JNL*/ + break; - default: - CALL_FUNC((uintptr_t)NF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + default: + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + break; + } + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static __inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static __inline void +BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: - addbyte(0x8a); /*MOV AL, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3a); /*CMP AL, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB16: - addbyte(0x66); /*MOV AX, flags_op1*/ - addbyte(0x8b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x66); /*CMP AX, flags_op2*/ - addbyte(0x3b); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; - case FLAGS_SUB32: - addbyte(0x8b); /*MOV EAX, flags_op1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op1)); - addbyte(0x3b); /*CMP EAX, flags_op2*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(flags_op2)); - if (not) - addbyte(0x7e); /*JLE*/ - else - addbyte(0x7f); /*JNLE*/ - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + addbyte(0x8a); /*MOV AL, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3a); /*CMP AL, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7e); /*JLE*/ + else + addbyte(0x7f); /*JNLE*/ + break; + case FLAGS_SUB16: + addbyte(0x66); /*MOV AX, flags_op1*/ + addbyte(0x8b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x66); /*CMP AX, flags_op2*/ + addbyte(0x3b); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7e); /*JLE*/ + else + addbyte(0x7f); /*JNLE*/ + break; + case FLAGS_SUB32: + addbyte(0x8b); /*MOV EAX, flags_op1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op1)); + addbyte(0x3b); /*CMP EAX, flags_op2*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(flags_op2)); + if (not ) + addbyte(0x7e); /*JLE*/ + else + addbyte(0x7f); /*JNLE*/ + break; - default: - if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) - { - addbyte(0x83); /*CMP flags_res, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(flags_res)); - addbyte(0); - addbyte(0x74); /*JZ +*/ - } - else - { - CALL_FUNC((uintptr_t)ZF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x75); /*JNZ +*/ - } - if (not) - addbyte(5+2+3+5+2+3+2+2+7+5+(timing_bt ? 4 : 0)); - else - addbyte(5+2+3+5+2+3+2+2); - - CALL_FUNC((uintptr_t)NF_SET); + default: + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { + addbyte(0x83); /*CMP flags_res, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(flags_res)); + addbyte(0); + addbyte(0x74); /*JZ +*/ + } else { + CALL_FUNC((uintptr_t) ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); - addbyte(0x0f); /*SETNE BL*/ - addbyte(0x95); - addbyte(0xc3); - CALL_FUNC((uintptr_t)VF_SET); - addbyte(0x85); /*TEST EAX,EAX*/ - addbyte(0xc0); - addbyte(0x0f); /*SETNE AL*/ - addbyte(0x95); - addbyte(0xc0); - addbyte(0x38); /*CMP AL, BL*/ - addbyte(0xd8); - if (not) - addbyte(0x75); /*JNZ +*/ - else - addbyte(0x74); /*JZ +*/ - break; - } - addbyte(7+5+(timing_bt ? 4 : 0)); - addbyte(0xC7); /*MOVL [pc], new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc+pc_offset+offset); - if (timing_bt) - { - addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(_cycles)); - addbyte(timing_bt); - } - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0x75); /*JNZ +*/ + } + if (not ) + addbyte(5 + 2 + 3 + 5 + 2 + 3 + 2 + 2 + 7 + 5 + (timing_bt ? 4 : 0)); + else + addbyte(5 + 2 + 3 + 5 + 2 + 3 + 2 + 2); + + CALL_FUNC((uintptr_t) NF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE BL*/ + addbyte(0x95); + addbyte(0xc3); + CALL_FUNC((uintptr_t) VF_SET); + addbyte(0x85); /*TEST EAX,EAX*/ + addbyte(0xc0); + addbyte(0x0f); /*SETNE AL*/ + addbyte(0x95); + addbyte(0xc0); + addbyte(0x38); /*CMP AL, BL*/ + addbyte(0xd8); + if (not ) + addbyte(0x75); /*JNZ +*/ + else + addbyte(0x74); /*JZ +*/ + break; + } + addbyte(7 + 5 + (timing_bt ? 4 : 0)); + addbyte(0xC7); /*MOVL [pc], new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_offset + offset); + if (timing_bt) { + addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(_cycles)); + addbyte(timing_bt); + } + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } - -static __inline void FP_ENTER(void) +static __inline void +FP_ENTER(void) { - if (codegen_fpu_entered) - return; + if (codegen_fpu_entered) + return; - addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x05); + addlong((uintptr_t) &cr0); + addbyte(0xc); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 7 + 5 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + addbyte(0xc7); /*MOV [ESP], 7*/ + addbyte(0x04); + addbyte(0x24); + addlong(7); + addbyte(0xe8); /*CALL x86_int*/ + addlong((uint32_t) x86_int - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + + codegen_fpu_entered = 1; +} + +static __inline void +FP_FLD(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x88); /*MOV tag[-1][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } else { + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(0x01); + } + + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(0x07); + addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ + addbyte(0x54); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ + addbyte(0x4c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x8a); /*MOV AL, [tag+EAX]*/ + addbyte(0x44); addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - - codegen_fpu_entered = 1; -} - -static __inline void FP_FLD(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP - 1) & 7); - addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); - addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); - addbyte(0x88); /*MOV tag[-1][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - else - { - addbyte(0x83); /*SUB EBX, 1*/ - addbyte(0xeb); - addbyte(0x01); - } - - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(0x07); - addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ - addbyte(0x54); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ - addbyte(0x4c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8a); /*MOV AL, [tag+EAX]*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EBX], AL*/ - addbyte(0x44); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ - addbyte(0x54); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - - addbyte(0x89); /*MOV [TOP], EBX*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} - -static __inline void FP_FST(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [tag+EAX]*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - - if (reg) - { - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - } - - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x88); /*MOV [tag+EAX], BL*/ - addbyte(0x5c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - } -} - -static __inline void FP_FXCH(int reg) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); - addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x55); - addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); - addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); - addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[reg][EBP], AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); - addbyte(0x88); /*MOV tag[0][EBP], AH*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EAX, [TOP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - addbyte(0x83); /*ADD EAX, reg*/ - addbyte(0xc0); - addbyte(reg); - - addbyte(0xdd); /*FLD [ST+EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(0x07); - addbyte(0xdd); /*FLD [ST+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP [ST+EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV CL, tag[EAX]*/ - addbyte(0x4c); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x8a); /*MOV DL, tag[EBX]*/ - addbyte(0x54); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EBX], CL*/ - addbyte(0x4c); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x88); /*MOV tag[EAX], DL*/ - addbyte(0x54); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0xbe); /*MOVL ESI, ST_int64*/ - addlong((uintptr_t)cpu_state.MM); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ - addbyte(0x0c); - addbyte(0xc6); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ - addbyte(0x14); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ - addbyte(0x0c); - addbyte(0xde); - addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ - addbyte(0x14); - addbyte(0xc6); - addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ - addbyte(0x4c); - addbyte(0xc6); - addbyte(0x04); - addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ - addbyte(0x54); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ - addbyte(0x4c); - addbyte(0xde); - addbyte(0x04); - addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ - addbyte(0x54); - addbyte(0xc6); - addbyte(0x04); - } -} - - -static __inline void FP_LOAD_S(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((uint8_t) cpu_state_offset(tag[0])); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdb); /*FISTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static __inline int FP_LOAD_REG_INT(int reg) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdb); /*FISTP [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - - return REG_EBX; -} -static __inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) -{ - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - if (reg) - { - addbyte(0x83); /*ADD EBX, reg*/ - addbyte(0xc3); - addbyte(reg); - addbyte(0x83); /*AND EBX, 7*/ - addbyte(0xe3); - addbyte(7); - } - if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) - { - /*If we know the register was loaded with FILDq in this block and - has not been modified, then we can skip most of the conversion - and just load the 64-bit integer representation directly */ - addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ - addbyte(0x4c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); - addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); - - return; - } - - addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ addbyte(0x44); addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_UINT64); - addbyte(0x74); /*JZ +*/ - addbyte(4+4+2); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x89); /*MOV [TOP], EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + } +} + +static __inline void +FP_FST(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + } else { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [tag+EAX]*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + + if (reg) { + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + } + + addbyte(0xdd); /*FSTP [ST+EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x88); /*MOV [tag+EAX], BL*/ + addbyte(0x5c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} + +static __inline void +FP_FXCH(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xf3); /*MOVQ XMM0, ST[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte(0x88); /*MOV tag[0][EBP], AH*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EAX, [TOP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + addbyte(0x83); /*ADD EAX, reg*/ + addbyte(0xc0); + addbyte(reg); + + addbyte(0xdd); /*FLD [ST+EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(0x07); + addbyte(0xdd); /*FLD [ST+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP [ST+EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV CL, tag[EAX]*/ + addbyte(0x4c); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x8a); /*MOV DL, tag[EBX]*/ + addbyte(0x54); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x88); /*MOV tag[EBX], CL*/ + addbyte(0x4c); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x88); /*MOV tag[EAX], DL*/ + addbyte(0x54); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0xbe); /*MOVL ESI, ST_int64*/ + addlong((uintptr_t) cpu_state.MM); + addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ + addbyte(0x0c); + addbyte(0xc6); + addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]*/ + addbyte(0x14); + addbyte(0xde); + addbyte(0x89); /*MOV ST_int64[EBX*8], ECX*/ + addbyte(0x0c); + addbyte(0xde); + addbyte(0x89); /*MOV ST_int64[EAX*8], EDX*/ + addbyte(0x14); + addbyte(0xc6); + addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]+4*/ + addbyte(0x4c); + addbyte(0xc6); + addbyte(0x04); + addbyte(0x8b); /*MOV EDX, ST_int64[EBX*8]+4*/ + addbyte(0x54); + addbyte(0xde); + addbyte(0x04); + addbyte(0x89); /*MOV ST_int64[EBX*8]+4, ECX*/ + addbyte(0x4c); + addbyte(0xde); + addbyte(0x04); + addbyte(0x89); /*MOV ST_int64[EAX*8]+4, EDX*/ + addbyte(0x54); + addbyte(0xc6); + addbyte(0x04); + } +} + +static __inline void +FP_LOAD_S(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0xd9); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xd9); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_D(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/ + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0xdd); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_IW(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0x66); /*TEST AX, AX*/ + addbyte(0x85); + addbyte(0xc0); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_IL(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x85); /*TEST EAX, EAX*/ + addbyte(0xc0); + addbyte(0xdb); /*FILDl [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x0f); /*SETE tag[reg][EBP]*/ + addbyte(0x94); + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdb); /*FILDl [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} +static __inline void +FP_LOAD_IQ(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/ + addbyte(0x55); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdf); /*FILDq MM[reg][EBP]*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0x88); /*MOV tag[reg][EBP], AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(0xdd); /*FSTP ST[reg][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ + addbyte(0x54); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ + addbyte(0x6c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + } +} + +static __inline void +FP_LOAD_IMM_Q(uint64_t v) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xc7); /*MOV ST[reg][EBP], v*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addlong(v & 0xffffffff); + addbyte(0xc7); /*MOV ST[reg][EBP]+4, v*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addlong(v >> 32); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP - 1) & 7); + addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte(v ? 0 : 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addlong(v & 0xffffffff); + addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST) + 4); + addlong(v >> 32); + addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(v ? 0 : 1); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + } +} + +static __inline int +FP_LOAD_REG(int reg) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[reg][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + addbyte(0xd9); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV EAX, [ESP]*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(0x24); + + return REG_EBX; +} + +static __inline void +FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[reg][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + addbyte(0xdd); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(0x24); + addbyte(0x8b); /*MOV ECX, [ESP+4]*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(0x24); + addbyte(0x04); + + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; +} + +static __inline int +FP_LOAD_REG_INT_W(int reg) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addbyte(0xdb); /*FISTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + + return REG_EBX; +} +static __inline int +FP_LOAD_REG_INT(int reg) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addbyte(0xdb); /*FISTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + + return REG_EBX; +} +static __inline void +FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + if (reg) { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + if (codegen_fpu_loaded_iq[cpu_state.TOP] && (cpu_state.tag[cpu_state.TOP] & TAG_UINT64)) { + /*If we know the register was loaded with FILDq in this block and + has not been modified, then we can skip most of the conversion + and just load the 64-bit integer representation directly */ addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ addbyte(0x4c); addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)+4); + addbyte((uint8_t) cpu_state_offset(MM) + 4); addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(MM)); + addbyte((uint8_t) cpu_state_offset(MM)); - addbyte(0xeb); /*JMP done*/ - addbyte(4+3+3+3+3+4); + return; + } - addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ + addbyte(0x44); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_UINT64); + addbyte(0x74); /*JZ +*/ + addbyte(4 + 4 + 2); + + addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ + addbyte(0x4c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM) + 4); + addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(MM)); + + addbyte(0xeb); /*JMP done*/ + addbyte(4 + 3 + 3 + 3 + 3 + 4); + + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addbyte(0xdf); /*FISTPQ [ESP]*/ + addbyte(0x3c); + addbyte(0x24); + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV ECX, 4[ESP]*/ + addbyte(0x4c); + addbyte(0x24); + addbyte(4); + + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; +} + +static __inline void +FP_POP(void) +{ + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(3); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP + 1) & 7); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addbyte(0xdf); /*FISTPQ [ESP]*/ - addbyte(0x3c); - addbyte(0x24); - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - addbyte(0x8b); /*MOV EBX, [ESP]*/ - addbyte(0x1c); - addbyte(0x24); - addbyte(0x8b); /*MOV ECX, 4[ESP]*/ - addbyte(0x4c); - addbyte(0x24); - addbyte(4); - - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(3); + addbyte(0x04); /*ADD AL, 1*/ + addbyte(1); + addbyte(0x24); /*AND AL, 7*/ + addbyte(7); + addbyte(0x88); /*MOV TOP, AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + } } - -static __inline void FP_POP(void) +static __inline void +FP_POP2(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(3); - addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte((cpu_state.TOP + 1) & 7); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0xc6); /*MOVB tag[EAX], 3*/ - addbyte(0x44); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(3); - addbyte(0x04); /*ADD AL, 1*/ - addbyte(1); - addbyte(0x24); /*AND AL, 7*/ - addbyte(7); - addbyte(0x88); /*MOV TOP, AL*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - } -} -static __inline void FP_POP2(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)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(3); + addbyte(0xc6); /*MOVB tag[1][EBP], 3*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + 1) & 7])); + addbyte(3); + addbyte(0xc6); /*MOVB TOP[EBP], (TOP+2) & 7*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte((cpu_state.TOP + 2) & 7); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0xc6); /*MOVB tag[EAX], 3*/ + addbyte(0x44); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(3); + addbyte(0x04); /*ADD AL, 2*/ + addbyte(2); + addbyte(0x24); /*AND AL, 7*/ + addbyte(7); + addbyte(0x88); /*MOV TOP, AL*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + } } #define FPU_ADD 0x00 @@ -2692,226 +2627,214 @@ static __inline void FP_POP2(void) #define FPU_SUB 0x20 #define FPU_SUBR 0x28 -static __inline void FP_OP_S(int op) +static __inline void +FP_OP_S(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xd8); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xd8); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xd8); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static __inline void FP_OP_D(int op) +static __inline void +FP_OP_D(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - } - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) - { - addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ - addbyte(0x6d); - addbyte((uint8_t)cpu_state_offset(old_npxc)); - } + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); } + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + } + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { + addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ + addbyte(0x6d); + addbyte((uint8_t) cpu_state_offset(old_npxc)); + } + } } -static __inline void FP_OP_IW(int op) +static __inline void +FP_OP_IW(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xde); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static __inline void FP_OP_IL(int op) +static __inline void +FP_OP_IL(int op) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); - addbyte(TAG_NOT_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP ST[0][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xda); /*FADD [ESP]*/ - addbyte(0x04 | op); - addbyte(0x24); - addbyte(0xdd); /*FSTP [ST+EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP ST[0][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } } #if 0 static __inline void FP_OP_IQ(int op) @@ -2971,1037 +2894,1032 @@ static __inline void FP_OP_IQ(int op) } #endif -static __inline void FP_COMPARE_S(void) +static __inline void +FP_COMPARE_S(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xd8); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static __inline void FP_COMPARE_D(void) +static __inline void +FP_COMPARE_D(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0x89); /*MOV [ESP+4], EDX*/ - addbyte(0x54); - addbyte(0x24); - addbyte(0x04); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static __inline void FP_COMPARE_IW(void) +static __inline void +FP_COMPARE_IW(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x66); /*MOV [ESP], AX*/ - addbyte(0x89); - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xde); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x66); /*MOV [ESP], AX*/ + addbyte(0x89); + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static __inline void FP_COMPARE_IL(void) +static __inline void +FP_COMPARE_IL(void) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[0][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EBX, TOP*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV [ESP], EAX*/ - addbyte(0x04); - addbyte(0x24); - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x8a); /*MOV BL, [npxs+1]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ - addbyte(0xe3); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xda); /*FCOMP [ESP]*/ - addbyte(0x04 | 0x18); - addbyte(0x24); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR BL, AH*/ - addbyte(0xe3); - addbyte(0x88); /*MOV [npxs+1], BL*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static __inline void FP_OP_REG(int op, int dst, int src) +static __inline void +FP_OP_REG(int op, int dst, int src) { - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0xdc); /*FADD ST[src][EBP]*/ - addbyte(0x45 | op); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ - addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdd); /*FSTP ST[dst][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x1d); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD ST[EAX*8]*/ - addbyte(0x44 | op); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EBX*8]*/ - addbyte(0x5c); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ - addbyte(0x64); - addbyte(0x05); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(TAG_NOT_UINT64); - addbyte(0xdc); /*FADD ST[EBX*8]*/ - addbyte(0x44 | op); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdd); /*FSTP ST[EAX*8]*/ - addbyte(0x5c); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - } -} - -static __inline void FP_COMPARE_REG(int dst, int src) -{ - if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) - { - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0xdd); /*FLD ST[dst][EBP]*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - addbyte(0xdc); /*FCOMP ST[src][EBP]*/ - addbyte(0x5d); - addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } - else - { - addbyte(0x8b); /*MOV EAX, TOP*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV EBX, EAX*/ - addbyte(0xc3); - if (src || dst) - { - addbyte(0x83); /*ADD EAX, 1*/ - addbyte(0xc0); - addbyte(src ? src : dst); - addbyte(0x83); /*AND EAX, 7*/ - addbyte(0xe0); - addbyte(7); - } - - addbyte(0x8a); /*MOV CL, [npxs+1]*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - addbyte(0xdb); /*FCLEX*/ - addbyte(0xe2); - addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ - addbyte(0xe1); - addbyte((~(C0|C2|C3)) >> 8); - - if (src) - { - addbyte(0xdd); /*FLD ST[EBX*8]*/ - addbyte(0x44); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EAX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - } - else - { - addbyte(0xdd); /*FLD [ESI+EAX*8]*/ - addbyte(0x44); - addbyte(0xc5); - addbyte((uint8_t)cpu_state_offset(ST)); - addbyte(0xdc); /*FCOMP ST[EBX*8]*/ - addbyte(0x44 | 0x18); - addbyte(0xdd); - addbyte((uint8_t)cpu_state_offset(ST)); - } - - addbyte(0xdf); /*FSTSW AX*/ - addbyte(0xe0); - addbyte(0x80); /*AND AH, (C0|C2|C3)*/ - addbyte(0xe4); - addbyte((C0|C2|C3) >> 8); - addbyte(0x08); /*OR CL, AH*/ - addbyte(0xe1); - addbyte(0x88); /*MOV [npxs+1], CL*/ - addbyte(0x4d); - addbyte((uint8_t)cpu_state_offset(npxs) + 1); - } -} - -static __inline void FP_FCHS(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); + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte(0xdc); /*FADD ST[src][EBP]*/ + addbyte(0x45 | op); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte((uint8_t)cpu_state_offset(new_npxc)); - addword(~0xc00); - if (reg) - { - addbyte(0x66); /*AND reg, 0xc00*/ - addbyte(0x81); - addbyte(0xe0 | reg); - addword(0xc00); + addbyte((uint8_t) cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); } - else - { - addbyte(0x66); /*AND AX, 0xc00*/ - addbyte(0x25); - addword(0xc00); + + if (src) { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x1d); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD ST[EAX*8]*/ + addbyte(0x44 | op); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP ST[EBX*8]*/ + addbyte(0x5c); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdc); /*FADD ST[EBX*8]*/ + addbyte(0x44 | op); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdd); /*FSTP ST[EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); } - addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ - addbyte(0x09); - addbyte(0x45 | (reg << 3)); - addbyte((uint8_t)cpu_state_offset(new_npxc)); + } } -static __inline int ZERO_EXTEND_W_B(int reg) +static __inline void +FP_COMPARE_REG(int dst, int src) { - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static __inline int ZERO_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regb*/ - addbyte(0xb6); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static __inline int ZERO_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVZX regl, regw*/ - addbyte(0xb7); - addbyte(0xc0 | reg | (reg << 3)); - return reg; + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0xdd); /*FLD ST[dst][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); + addbyte(0xdc); /*FCOMP ST[src][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0 | C2 | C3)) >> 8); + + if (src) { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x44); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdc); /*FCOMP ST[EAX*8]*/ + addbyte(0x44 | 0x18); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } else { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0xdc); /*FCOMP ST[EBX*8]*/ + addbyte(0x44 | 0x18); + addbyte(0xdd); + addbyte((uint8_t) cpu_state_offset(ST)); + } + + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0 | C2 | C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x4d); + addbyte((uint8_t) cpu_state_offset(npxs) + 1); + } } -static __inline int SIGN_EXTEND_W_B(int reg) +static __inline void +FP_FCHS(void) { - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static __inline int SIGN_EXTEND_L_B(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regb*/ - addbyte(0xbe); - addbyte(0xc0 | reg | (reg << 3)); - return reg; -} -static __inline int SIGN_EXTEND_L_W(int reg) -{ - addbyte(0x0f); /*MOVSX regl, regw*/ - addbyte(0xbf); - addbyte(0xc0 | reg | (reg << 3)); - return reg; + if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { + addbyte(0xdd); /*FLD ST[0][EBP]*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + addbyte(0xd9); /*FCHS*/ + addbyte(0xe0); + addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(tag[cpu_state.TOP])); + addbyte(TAG_NOT_UINT64); + addbyte(0xdd); /*FSTP ST[dst][EBP]*/ + addbyte(0x5d); + addbyte((uint8_t) cpu_state_offset(ST[cpu_state.TOP])); + } else { + addbyte(0x8b); /*MOV EAX, TOP*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x44); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ + addbyte(0x64); + addbyte(0x05); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(TAG_NOT_UINT64); + addbyte(0xd9); /*FCHS*/ + addbyte(0xe0); + addbyte(0xdd); /*FSTP ST[EAX*8]*/ + addbyte(0x5c); + addbyte(0xc5); + addbyte((uint8_t) cpu_state_offset(ST)); + } } -static __inline int COPY_REG(int src_reg) +static __inline void +UPDATE_NPXC(int reg) { - return src_reg; + addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/ + addbyte(0x81); + addbyte(0x65); + addbyte((uint8_t) cpu_state_offset(new_npxc)); + addword(~0xc00); + if (reg) { + addbyte(0x66); /*AND reg, 0xc00*/ + addbyte(0x81); + addbyte(0xe0 | reg); + addword(0xc00); + } else { + addbyte(0x66); /*AND AX, 0xc00*/ + addbyte(0x25); + addword(0xc00); + } + addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ + addbyte(0x09); + addbyte(0x45 | (reg << 3)); + addbyte((uint8_t) cpu_state_offset(new_npxc)); } -static __inline void SET_BITS(uintptr_t addr, uint32_t val) +static __inline int +ZERO_EXTEND_W_B(int reg) { - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x0d); - addlong(addr); - addlong(val); - } - else - { - addbyte(0x80); - addbyte(0x0d); - addlong(addr); - addbyte(val); - } + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | reg | (reg << 3)); + return reg; } -static __inline void CLEAR_BITS(uintptr_t addr, uint32_t val) +static __inline int +ZERO_EXTEND_L_B(int reg) { - if (val & ~0xff) - { - addbyte(0x81); - addbyte(0x25); - addlong(addr); - addlong(~val); - } - else - { - addbyte(0x80); - addbyte(0x25); - addlong(addr); - addbyte(~val); - } + addbyte(0x0f); /*MOVZX regl, regb*/ + addbyte(0xb6); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} +static __inline int +ZERO_EXTEND_L_W(int reg) +{ + addbyte(0x0f); /*MOVZX regl, regw*/ + addbyte(0xb7); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} + +static __inline int +SIGN_EXTEND_W_B(int reg) +{ + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} +static __inline int +SIGN_EXTEND_L_B(int reg) +{ + addbyte(0x0f); /*MOVSX regl, regb*/ + addbyte(0xbe); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} +static __inline int +SIGN_EXTEND_L_W(int reg) +{ + addbyte(0x0f); /*MOVSX regl, regw*/ + addbyte(0xbf); + addbyte(0xc0 | reg | (reg << 3)); + return reg; +} + +static __inline int +COPY_REG(int src_reg) +{ + return src_reg; +} + +static __inline void +SET_BITS(uintptr_t addr, uint32_t val) +{ + if (val & ~0xff) { + addbyte(0x81); + addbyte(0x0d); + addlong(addr); + addlong(val); + } else { + addbyte(0x80); + addbyte(0x0d); + addlong(addr); + addbyte(val); + } +} +static __inline void +CLEAR_BITS(uintptr_t addr, uint32_t val) +{ + if (val & ~0xff) { + addbyte(0x81); + addbyte(0x25); + addlong(addr); + addlong(~val); + } else { + addbyte(0x80); + addbyte(0x25); + addlong(addr); + addbyte(~val); + } } #define LOAD_Q_REG_1 REG_EAX #define LOAD_Q_REG_2 REG_EDX -static __inline void MMX_ENTER(void) +static __inline void +MMX_ENTER(void) { - if (codegen_mmx_entered) - return; + if (codegen_mmx_entered) + return; - addbyte(0xf6); /*TEST cr0, 0xc*/ - addbyte(0x05); - addlong((uintptr_t)&cr0); - addbyte(0xc); - addbyte(0x74); /*JZ +*/ - addbyte(7+7+5+5); - addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(op_old_pc); - addbyte(0xc7); /*MOV [ESP], 7*/ - addbyte(0x04); - addbyte(0x24); - addlong(7); - addbyte(0xe8); /*CALL x86_int*/ - addlong((uint32_t)x86_int - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - addbyte(0xe9); /*JMP end*/ - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0xf6); /*TEST cr0, 0xc*/ + addbyte(0x05); + addlong((uintptr_t) &cr0); + addbyte(0xc); + addbyte(0x74); /*JZ +*/ + addbyte(7 + 7 + 5 + 5); + addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(op_old_pc); + addbyte(0xc7); /*MOV [ESP], 7*/ + addbyte(0x04); + addbyte(0x24); + addlong(7); + addbyte(0xe8); /*CALL x86_int*/ + addlong((uint32_t) x86_int - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0xe9); /*JMP end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); - addbyte(0x31); /*XOR EAX, EAX*/ - addbyte(0xc0); - addbyte(0xc6); /*MOV ISMMX, 1*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ismmx)); - addbyte(1); - addbyte(0x89); /*MOV TOP, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(TOP)); - addbyte(0x89); /*MOV tag, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[0])); - addbyte(0x89); /*MOV tag+4, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(tag[4])); + addbyte(0x31); /*XOR EAX, EAX*/ + addbyte(0xc0); + addbyte(0xc6); /*MOV ISMMX, 1*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ismmx)); + addbyte(1); + addbyte(0x89); /*MOV TOP, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(TOP)); + addbyte(0x89); /*MOV tag, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[0])); + addbyte(0x89); /*MOV tag+4, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(tag[4])); - codegen_mmx_entered = 1; + codegen_mmx_entered = 1; } extern int mmx_ebx_ecx_loaded; -static __inline int LOAD_MMX_D(int guest_reg) +static __inline int +LOAD_MMX_D(int guest_reg) { - int host_reg = find_host_reg(); - host_reg_mapping[host_reg] = 100; + int host_reg = find_host_reg(); + host_reg_mapping[host_reg] = 100; - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x8b); /*MOV EBX, reg*/ + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); - return host_reg; + return host_reg; } -static __inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +static __inline void +LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) { - if (!mmx_ebx_ecx_loaded) - { - *host_reg1 = REG_EBX; - *host_reg2 = REG_ECX; - mmx_ebx_ecx_loaded = 1; - } - else - { - *host_reg1 = REG_EAX; - *host_reg2 = REG_EDX; - } + if (!mmx_ebx_ecx_loaded) { + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; + mmx_ebx_ecx_loaded = 1; + } else { + *host_reg1 = REG_EAX; + *host_reg2 = REG_EDX; + } - addbyte(0x8b); /*MOV EBX, reg*/ - addbyte(0x45 | ((*host_reg1) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x8b); /*MOV ECX, reg+4*/ - addbyte(0x45 | ((*host_reg2) << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); + addbyte(0x8b); /*MOV EBX, reg*/ + addbyte(0x45 | ((*host_reg1) << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x8b); /*MOV ECX, reg+4*/ + addbyte(0x45 | ((*host_reg2) << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); } -static __inline int LOAD_MMX_Q_MMX(int guest_reg) +static __inline int +LOAD_MMX_Q_MMX(int guest_reg) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = guest_reg; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = guest_reg; - addbyte(0xf3); /*MOVQ dst_reg,[reg]*/ - addbyte(0x0f); - addbyte(0x7e); - addbyte(0x45 | (dst_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0xf3); /*MOVQ dst_reg,[reg]*/ + addbyte(0x0f); + addbyte(0x7e); + addbyte(0x45 | (dst_reg << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); - return dst_reg; + return dst_reg; } -static __inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +static __inline int +LOAD_INT_TO_MMX(int src_reg1, int src_reg2) { - int dst_reg = find_host_xmm_reg(); - host_reg_xmm_mapping[dst_reg] = 100; + int dst_reg = find_host_xmm_reg(); + host_reg_xmm_mapping[dst_reg] = 100; - addbyte(0x66); /*MOVD dst_reg, src_reg1*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (dst_reg << 3) | src_reg1); - addbyte(0x66); /*MOVD XMM7, src_reg2*/ - addbyte(0x0f); - addbyte(0x6e); - addbyte(0xc0 | (7 << 3) | src_reg2); - addbyte(0x66); /*PUNPCKLDQ dst_reg, XMM7*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | 7 | (dst_reg << 3)); + addbyte(0x66); /*MOVD dst_reg, src_reg1*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0 | (dst_reg << 3) | src_reg1); + addbyte(0x66); /*MOVD XMM7, src_reg2*/ + addbyte(0x0f); + addbyte(0x6e); + addbyte(0xc0 | (7 << 3) | src_reg2); + addbyte(0x66); /*PUNPCKLDQ dst_reg, XMM7*/ + addbyte(0x0f); + addbyte(0x62); + addbyte(0xc0 | 7 | (dst_reg << 3)); - return dst_reg; + return dst_reg; } -static __inline void STORE_MMX_LQ(int guest_reg, int host_reg1) +static __inline void +STORE_MMX_LQ(int guest_reg, int host_reg1) { - addbyte(0xC7); /*MOVL [reg],0*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); - addlong(0); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg1 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0xC7); /*MOVL [reg],0*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); + addlong(0); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg1 << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); } -static __inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +static __inline void +STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) { - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg1 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); - addbyte(0x89); /*MOVL [reg],host_reg*/ - addbyte(0x45 | (host_reg2 << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg1 << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[0])); + addbyte(0x89); /*MOVL [reg],host_reg*/ + addbyte(0x45 | (host_reg2 << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].l[1])); } -static __inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) +static __inline void +STORE_MMX_Q_MMX(int guest_reg, int host_reg) { - addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ - addbyte(0x0f); - addbyte(0xd6); - addbyte(0x45 | (host_reg << 3)); - addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); + addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ + addbyte(0x0f); + addbyte(0xd6); + addbyte(0x45 | (host_reg << 3)); + addbyte((uint8_t) cpu_state_offset(MM[guest_reg].q)); } -#define MMX_x86_OP(name, opcode) \ -static __inline void MMX_ ## name(int dst_reg, int src_reg) \ -{ \ - addbyte(0x66); /*op dst_reg, src_reg*/ \ - addbyte(0x0f); \ - addbyte(opcode); \ - addbyte(0xc0 | (dst_reg << 3) | src_reg); \ -} +#define MMX_x86_OP(name, opcode) \ + static __inline void MMX_##name(int dst_reg, int src_reg) \ + { \ + addbyte(0x66); /*op dst_reg, src_reg*/ \ + addbyte(0x0f); \ + addbyte(opcode); \ + addbyte(0xc0 | (dst_reg << 3) | src_reg); \ + } -MMX_x86_OP(AND, 0xdb) -MMX_x86_OP(ANDN, 0xdf) -MMX_x86_OP(OR, 0xeb) -MMX_x86_OP(XOR, 0xef) +MMX_x86_OP(AND, 0xdb) + MMX_x86_OP(ANDN, 0xdf) + MMX_x86_OP(OR, 0xeb) + MMX_x86_OP(XOR, 0xef) -MMX_x86_OP(ADDB, 0xfc) -MMX_x86_OP(ADDW, 0xfd) -MMX_x86_OP(ADDD, 0xfe) -MMX_x86_OP(ADDSB, 0xec) -MMX_x86_OP(ADDSW, 0xed) -MMX_x86_OP(ADDUSB, 0xdc) -MMX_x86_OP(ADDUSW, 0xdd) + MMX_x86_OP(ADDB, 0xfc) + MMX_x86_OP(ADDW, 0xfd) + MMX_x86_OP(ADDD, 0xfe) + MMX_x86_OP(ADDSB, 0xec) + MMX_x86_OP(ADDSW, 0xed) + MMX_x86_OP(ADDUSB, 0xdc) + MMX_x86_OP(ADDUSW, 0xdd) -MMX_x86_OP(SUBB, 0xf8) -MMX_x86_OP(SUBW, 0xf9) -MMX_x86_OP(SUBD, 0xfa) -MMX_x86_OP(SUBSB, 0xe8) -MMX_x86_OP(SUBSW, 0xe9) -MMX_x86_OP(SUBUSB, 0xd8) -MMX_x86_OP(SUBUSW, 0xd9) + MMX_x86_OP(SUBB, 0xf8) + MMX_x86_OP(SUBW, 0xf9) + MMX_x86_OP(SUBD, 0xfa) + MMX_x86_OP(SUBSB, 0xe8) + MMX_x86_OP(SUBSW, 0xe9) + MMX_x86_OP(SUBUSB, 0xd8) + MMX_x86_OP(SUBUSW, 0xd9) -MMX_x86_OP(PUNPCKLBW, 0x60); + MMX_x86_OP(PUNPCKLBW, 0x60); MMX_x86_OP(PUNPCKLWD, 0x61); MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); +MMX_x86_OP(PCMPGTB, 0x64); +MMX_x86_OP(PCMPGTW, 0x65); +MMX_x86_OP(PCMPGTD, 0x66); -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); +MMX_x86_OP(PCMPEQB, 0x74); +MMX_x86_OP(PCMPEQW, 0x75); +MMX_x86_OP(PCMPEQD, 0x76); -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); +MMX_x86_OP(PSRLW, 0xd1); +MMX_x86_OP(PSRLD, 0xd2); +MMX_x86_OP(PSRLQ, 0xd3); +MMX_x86_OP(PSRAW, 0xe1); +MMX_x86_OP(PSRAD, 0xe2); +MMX_x86_OP(PSLLW, 0xf1); +MMX_x86_OP(PSLLD, 0xf2); +MMX_x86_OP(PSLLQ, 0xf3); -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); +MMX_x86_OP(PMULLW, 0xd5); +MMX_x86_OP(PMULHW, 0xe5); MMX_x86_OP(PMADDWD, 0xf5); -static __inline void MMX_PACKSSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x63); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x63); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static __inline void MMX_PACKUSWB(int dst_reg, int src_reg) +static __inline void +MMX_PACKUSWB(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x67); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x67); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static __inline void MMX_PACKSSDW(int dst_reg, int src_reg) +static __inline void +MMX_PACKSSDW(int dst_reg, int src_reg) { - addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x6b); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x08); + addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x6b); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x08); } -static __inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHBW(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x60); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x60); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static __inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHWD(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x61); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x61); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static __inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) +static __inline void +MMX_PUNPCKHDQ(int dst_reg, int src_reg) { - addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ - addbyte(0x0f); - addbyte(0x62); - addbyte(0xc0 | (dst_reg << 3) | src_reg); - addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ - addbyte(0x0f); - addbyte(0x70); - addbyte(0xc0 | (dst_reg << 3) | dst_reg); - addbyte(0x0e); + addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ + addbyte(0x0f); + addbyte(0x62); + addbyte(0xc0 | (dst_reg << 3) | src_reg); + addbyte(0x66); /*PSHUFD dst_reg, dst_reg*/ + addbyte(0x0f); + addbyte(0x70); + addbyte(0xc0 | (dst_reg << 3) | dst_reg); + addbyte(0x0e); } -static __inline void MMX_PSRLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static __inline void MMX_PSRAW_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static __inline void MMX_PSLLW_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLW_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLW dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x71); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLW dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x71); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static __inline void MMX_PSRLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static __inline void MMX_PSRAD_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static __inline void MMX_PSLLD_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLD_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLD dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x72); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLD dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x72); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } -static __inline void MMX_PSRLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x10); - addbyte(amount); + addbyte(0x66); /*PSRLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x10); + addbyte(amount); } -static __inline void MMX_PSRAQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSRAQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSRAQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x20); - addbyte(amount); + addbyte(0x66); /*PSRAQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x20); + addbyte(amount); } -static __inline void MMX_PSLLQ_imm(int dst_reg, int amount) +static __inline void +MMX_PSLLQ_imm(int dst_reg, int amount) { - addbyte(0x66); /*PSLLQ dst_reg, amount*/ - addbyte(0x0f); - addbyte(0x73); - addbyte(0xc0 | dst_reg | 0x30); - addbyte(amount); + addbyte(0x66); /*PSLLQ dst_reg, amount*/ + addbyte(0x0f); + addbyte(0x73); + addbyte(0xc0 | dst_reg | 0x30); + addbyte(amount); } - -static __inline void SAVE_EA(void) +static __inline void +SAVE_EA(void) { - addbyte(0x89); /*MOV [ESP+12], EAX*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); + addbyte(0x89); /*MOV [ESP+12], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(12); } -static __inline void LOAD_EA(void) +static __inline void +LOAD_EA(void) { - addbyte(0x8b); /*MOV EAX, [ESP+12]*/ - addbyte(0x44); - addbyte(0x24); - addbyte(12); + addbyte(0x8b); /*MOV EAX, [ESP+12]*/ + addbyte(0x44); + addbyte(0x24); + addbyte(12); } #define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static __inline void MEM_CHECK_WRITE(x86seg *seg) +static __inline void +MEM_CHECK_WRITE(x86seg *seg) { - CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write*/ - addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); + CHECK_SEG_WRITE(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_check_write*/ + addlong(mem_check_write - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + LOAD_EA(); } -static __inline void MEM_CHECK_WRITE_W(x86seg *seg) +static __inline void +MEM_CHECK_WRITE_W(x86seg *seg) { - CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write_w*/ - addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); + CHECK_SEG_WRITE(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_check_write_w*/ + addlong(mem_check_write_w - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + LOAD_EA(); } -static __inline void MEM_CHECK_WRITE_L(x86seg *seg) +static __inline void +MEM_CHECK_WRITE_L(x86seg *seg) { - CHECK_SEG_WRITE(seg); - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } - addbyte(0xe8); /*CALL mem_check_write_l*/ - addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); - LOAD_EA(); + CHECK_SEG_WRITE(seg); + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } else { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t) &seg->base); + } + addbyte(0xe8); /*CALL mem_check_write_l*/ + addlong(mem_check_write_l - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + LOAD_EA(); } -static __inline void LOAD_SEG(int host_reg, void *seg) +static __inline void +LOAD_SEG(int host_reg, void *seg) { - addbyte(0xc7); /*MOV [ESP+4], seg*/ - addbyte(0x44); - addbyte(0x24); - addbyte(4); - addlong((uint32_t)seg); - addbyte(0x89); /*MOV [ESP], host_reg*/ - addbyte(0x04 | (host_reg << 3)); - addbyte(0x24); - CALL_FUNC((uintptr_t)loadseg); - addbyte(0x80); /*CMP abrt, 0*/ - addbyte(0x7d); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(0); - addbyte(0x0f); /*JNE end*/ - addbyte(0x85); - addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + addbyte(0xc7); /*MOV [ESP+4], seg*/ + addbyte(0x44); + addbyte(0x24); + addbyte(4); + addlong((uint32_t) seg); + addbyte(0x89); /*MOV [ESP], host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(0x24); + CALL_FUNC((uintptr_t) loadseg); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } diff --git a/src/codegen/codegen_ops_xchg.h b/src/codegen/codegen_ops_xchg.h index a51f42eda..071acc3d8 100644 --- a/src/codegen/codegen_ops_xchg.h +++ b/src/codegen/codegen_ops_xchg.h @@ -1,16 +1,16 @@ -#define OP_XCHG_AX_(reg) \ - static uint32_t ropXCHG_AX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int ax_reg, host_reg, temp_reg; \ - \ - ax_reg = LOAD_REG_W(REG_AX); \ - host_reg = LOAD_REG_W(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_W_RELEASE(ax_reg, REG_ ## reg); \ - STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ - \ - return op_pc; \ - } +#define OP_XCHG_AX_(reg) \ + static uint32_t ropXCHG_AX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int ax_reg, host_reg, temp_reg; \ + \ + ax_reg = LOAD_REG_W(REG_AX); \ + host_reg = LOAD_REG_W(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_W_RELEASE(ax_reg, REG_##reg); \ + STORE_REG_TARGET_W_RELEASE(temp_reg, REG_AX); \ + \ + return op_pc; \ + } OP_XCHG_AX_(BX) OP_XCHG_AX_(CX) @@ -20,19 +20,19 @@ OP_XCHG_AX_(DI) OP_XCHG_AX_(SP) OP_XCHG_AX_(BP) -#define OP_XCHG_EAX_(reg) \ - static uint32_t ropXCHG_EAX_ ## reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ - { \ - int eax_reg, host_reg, temp_reg; \ - \ - eax_reg = LOAD_REG_L(REG_EAX); \ - host_reg = LOAD_REG_L(REG_ ## reg); \ - temp_reg = COPY_REG(host_reg); \ - STORE_REG_TARGET_L_RELEASE(eax_reg, REG_ ## reg); \ - STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ - \ - return op_pc; \ - } +#define OP_XCHG_EAX_(reg) \ + static uint32_t ropXCHG_EAX_##reg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ + { \ + int eax_reg, host_reg, temp_reg; \ + \ + eax_reg = LOAD_REG_L(REG_EAX); \ + host_reg = LOAD_REG_L(REG_##reg); \ + temp_reg = COPY_REG(host_reg); \ + STORE_REG_TARGET_L_RELEASE(eax_reg, REG_##reg); \ + STORE_REG_TARGET_L_RELEASE(temp_reg, REG_EAX); \ + \ + return op_pc; \ + } OP_XCHG_EAX_(EBX) OP_XCHG_EAX_(ECX) @@ -42,48 +42,51 @@ OP_XCHG_EAX_(EDI) OP_XCHG_EAX_(ESP) OP_XCHG_EAX_(EBP) -static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg, temp_reg; + int src_reg, dst_reg, temp_reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) != 0xc0) + return 0; - dst_reg = LOAD_REG_B(fetchdat & 7); - src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); + dst_reg = LOAD_REG_B(fetchdat & 7); + src_reg = LOAD_REG_B((fetchdat >> 3) & 7); + temp_reg = COPY_REG(src_reg); + STORE_REG_TARGET_B_RELEASE(dst_reg, (fetchdat >> 3) & 7); + STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg, temp_reg; + int src_reg, dst_reg, temp_reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) != 0xc0) + return 0; - dst_reg = LOAD_REG_W(fetchdat & 7); - src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7); + dst_reg = LOAD_REG_W(fetchdat & 7); + src_reg = LOAD_REG_W((fetchdat >> 3) & 7); + temp_reg = COPY_REG(src_reg); + STORE_REG_TARGET_W_RELEASE(dst_reg, (fetchdat >> 3) & 7); + STORE_REG_TARGET_W_RELEASE(temp_reg, fetchdat & 7); - return op_pc + 1; + return op_pc + 1; } -static uint32_t ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropXCHG_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int src_reg, dst_reg, temp_reg; + int src_reg, dst_reg, temp_reg; - if ((fetchdat & 0xc0) != 0xc0) - return 0; + if ((fetchdat & 0xc0) != 0xc0) + return 0; - dst_reg = LOAD_REG_L(fetchdat & 7); - src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - temp_reg = COPY_REG(src_reg); - STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7); - STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7); + dst_reg = LOAD_REG_L(fetchdat & 7); + src_reg = LOAD_REG_L((fetchdat >> 3) & 7); + temp_reg = COPY_REG(src_reg); + STORE_REG_TARGET_L_RELEASE(dst_reg, (fetchdat >> 3) & 7); + STORE_REG_TARGET_L_RELEASE(temp_reg, fetchdat & 7); - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index 6ee277f72..6939819d4 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -1,1188 +1,1116 @@ #if defined __amd64__ || defined _M_X64 -#include -#include -#include -#include -#include -#define HAVE_STDARG_H -#include <86box/86box.h> -#include "cpu.h" -#include "x86.h" -#include "x86_flags.h" -#include "x86_ops.h" -#include "x87.h" -#include <86box/mem.h> +# include +# include +# include +# include +# include +# define HAVE_STDARG_H +# include <86box/86box.h> +# include "cpu.h" +# include "x86.h" +# include "x86_flags.h" +# include "x86_ops.h" +# include "x87.h" +# include <86box/mem.h> -#include "386_common.h" +# include "386_common.h" -#include "codegen.h" -#include "codegen_accumulate.h" -#include "codegen_ops.h" -#include "codegen_ops_x86-64.h" +# include "codegen.h" +# include "codegen_accumulate.h" +# include "codegen_ops.h" +# include "codegen_ops_x86-64.h" -#if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) -#include -#include -#endif -#if _WIN64 -#include -#endif +# if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) +# include +# include +# endif +# if _WIN64 +# include +# endif -int codegen_flat_ds, codegen_flat_ss; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_fpu_loaded_iq[8]; -int codegen_reg_loaded[8]; -x86seg *op_ea_seg; -int op_ssegs; +int codegen_flat_ds, codegen_flat_ss; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_fpu_loaded_iq[8]; +int codegen_reg_loaded[8]; +x86seg *op_ea_seg; +int op_ssegs; uint32_t op_old_pc; uint32_t recomp_page = -1; -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; +int host_reg_mapping[NR_HOST_REGS]; +int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; +codeblock_t *codeblock; codeblock_t **codeblock_hash; -int codegen_mmx_entered = 0; +int codegen_mmx_entered = 0; -int block_current = 0; +int block_current = 0; static int block_num; -int block_pos; +int block_pos; uint32_t codegen_endpc; -int codegen_block_cycles; +int codegen_block_cycles; static int codegen_block_ins; static int codegen_block_full_ins; static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; +static x86seg *last_ea_seg; +static int last_ssegs; -void codegen_init(void) +void +codegen_init(void) { - int c; + int c; -#if _WIN64 - codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) - codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); -#else - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); +# if _WIN64 + codeblock = VirtualAlloc(NULL, BLOCK_SIZE * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +# elif defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) + codeblock = mmap(NULL, BLOCK_SIZE * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); +# else + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); +# endif + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].valid = 0; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].valid = 0; } -void codegen_reset(void) +void +codegen_reset(void) { - int c; + int c; - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + mem_reset_page_blocks(); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].valid = 0; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].valid = 0; } -void dump_block(void) +void +dump_block(void) { } -static void add_to_block_list(codeblock_t *block) +static void +add_to_block_list(codeblock_t *block) { - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); + if (!block->page_mask) + fatal("add_to_block_list - mask = 0\n"); - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (block->next->valid == 0) - fatal("block->next->valid=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - - if (block_prev) - { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } + if (block_prev) { + block->next = block_prev; + block_prev->prev = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } else { + block->next = NULL; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } + + if (block->next) { + if (block->next->valid == 0) + fatal("block->next->valid=0 %p %p %x %x\n", (void *) block->next, (void *) codeblock, block_current, block_pos); + } + + if (block->page_mask2) { + block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; + + if (block_prev) { + block->next_2 = block_prev; + block_prev->prev_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + } else { + block->next_2 = NULL; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } + } } -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; - if (block->next_2) - block->next_2->prev_2 = NULL; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (block->valid == 0) - fatal("Deleting deleted block\n"); - block->valid = 0; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - - block_current = (block_current + 1) & BLOCK_MASK; - block = &codeblock[block_current]; - - if (block->valid != 0) - { - delete_block(block); - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->valid = 1; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->pnt = block_current; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - block->dirty_mask2 = NULL; - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - block->page_mask = 0; - block->flags = 0; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - uintptr_t rip_rel; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; -#ifdef OLD_GPF -#if _WIN64 - addbyte(0x48); /*XOR RCX, RCX*/ - addbyte(0x31); - addbyte(0xc9); - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); -#else - addbyte(0x48); /*XOR RDI, RDI*/ - addbyte(0x31); - addbyte(0xff); - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); -#endif - call(block, (uintptr_t)x86gpf); - while (block_pos < BLOCK_EXIT_OFFSET) - addbyte(0x90); /*NOP*/ -#else - addbyte(0xC6); /*MOVB ABRT_GPF,(abrt)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(abrt)); - addbyte(ABRT_GPF); - addbyte(0x31); /* xor eax,eax */ - addbyte(0xc0); - addbyte(0x89); /*MOVB eax,(abrt_error)*/ - addbyte(0x85); - rip_rel = ((uintptr_t)&cpu_state) + 128; - rip_rel = ((uintptr_t) &(abrt_error)) - rip_rel; - addlong((uint32_t) rip_rel); -#endif - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x28); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH RBX*/ - addbyte(0x55); /*PUSH RBP*/ - addbyte(0x56); /*PUSH RSI*/ - addbyte(0x57); /*PUSH RDI*/ - addbyte(0x41); /*PUSH R12*/ - addbyte(0x54); - addbyte(0x41); /*PUSH R13*/ - addbyte(0x55); - addbyte(0x41); /*PUSH R14*/ - addbyte(0x56); - addbyte(0x41); /*PUSH R15*/ - addbyte(0x57); - addbyte(0x48); /*SUBL $40,%rsp*/ - addbyte(0x83); - addbyte(0xEC); - addbyte(0x28); - addbyte(0x48); /*MOVL RBP, &cpu_state*/ - addbyte(0xBD); - addquad(((uintptr_t)&cpu_state) + 128); - - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - - codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = - codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; - - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); -} - -void codegen_block_remove(void) -{ - codeblock_t *block = &codeblock[block_current]; - - delete_block(block); - - recomp_page = -1; -} - -void codegen_block_generate_end_mask(void) -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - - block->endpc = codegen_endpc; - - block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; - else - end_pc = (block->endpc & 0x3ff) & ~15; - if (end_pc < start_pc) - end_pc = 0x3ff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; - - for (; start_pc <= end_pc; start_pc++) - block->page_mask |= ((uint64_t)1 << start_pc); - - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (block->next_2->valid == 0) - fatal("block->next_2->valid=0 %p\n", (void *)block->next_2); - } - - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } - - recomp_page = -1; -} - -void codegen_block_end(void) -{ - codeblock_t *block = &codeblock[block_current]; - - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - - codegen_accumulate_flush(); - - addbyte(0x48); /*ADDL $40,%rsp*/ - addbyte(0x83); - addbyte(0xC4); - addbyte(0x28); - addbyte(0x41); /*POP R15*/ - addbyte(0x5f); - addbyte(0x41); /*POP R14*/ - addbyte(0x5e); - addbyte(0x41); /*POP R13*/ - addbyte(0x5d); - addbyte(0x41); /*POP R12*/ - addbyte(0x5c); - addbyte(0x5f); /*POP RDI*/ - addbyte(0x5e); /*POP RSI*/ - addbyte(0x5d); /*POP RBP*/ - addbyte(0x5b); /*POP RDX*/ - addbyte(0xC3); /*RET*/ - - if (block_pos > BLOCK_GPF_OFFSET) - fatal("Over limit!\n"); - - remove_from_block_list(block, block->pc); - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - codegen_block_generate_end_mask(); - add_to_block_list(block); -} - -void codegen_flush(void) +static void +remove_from_block_list(codeblock_t *block, uint32_t pc) { + if (!block->page_mask) return; -} -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug(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; - } + if (block->prev) { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } else { + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; + if (block->next) + block->next->prev = NULL; else - { - int base_reg = 0, index_reg = 0; + mem_flush_write_page(block->phys, 0); + } + if (!block->page_mask2) { + if (block->prev_2 || block->next_2) + fatal("Invalid block_2\n"); + return; + } - switch (cpu_rm) - { - case 0: case 1: case 7: - base_reg = LOAD_REG_W(REG_BX); - break; - case 2: case 3: case 6: - base_reg = LOAD_REG_W(REG_BP); - break; - case 4: - base_reg = LOAD_REG_W(REG_SI); - break; - case 5: - base_reg = LOAD_REG_W(REG_DI); - break; - } - if (!(cpu_rm & 4)) - { - if (cpu_rm & 1) - index_reg = LOAD_REG_W(REG_DI); - else - index_reg = LOAD_REG_W(REG_SI); - } - base_reg &= 7; - index_reg &= 7; - - switch (cpu_mod) - { - case 0: - if (cpu_rm & 4) - { - addbyte(0x41); /*MOVZX EAX, base_reg*/ - addbyte(0x0f); - addbyte(0xb7); - addbyte(0xc0 | base_reg); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3)); - } - } - break; - case 1: - if (cpu_rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3)); - addbyte((fetchdat >> 8) & 0xff); - } - (*op_pc)++; - break; - case 2: - if (cpu_rm & 4) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong((fetchdat >> 8) & 0xffff); - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3)); - addlong((fetchdat >> 8) & 0xffff); - } - (*op_pc) += 2; - break; - - } - if (cpu_mod || !(cpu_rm & 4)) - { - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - } - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; + if (block->prev_2) { + block->prev_2->next_2 = block->next_2; + if (block->next_2) + block->next_2->prev_2 = block->prev_2; + } else { + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; + if (block->next_2) + block->next_2->prev_2 = NULL; + else + mem_flush_write_page(block->phys_2, 0); + } } -//#if 0 -static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) + +static void +delete_block(codeblock_t *block) { - uint32_t new_eaaddr; + uint32_t old_pc = block->pc; - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; - int base_reg = -1, index_reg = -1; + if (block == codeblock_hash[HASH(block->phys)]) + codeblock_hash[HASH(block->phys)] = NULL; + if (block->valid == 0) + fatal("Deleting deleted block\n"); + block->valid = 0; + + codeblock_tree_delete(block); + remove_from_block_list(block, old_pc); +} + +void +codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +{ + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask) { + delete_block(block); + } + if (block == block->next) + fatal("Broken 1\n"); + block = block->next; + } + + block = page->block_2[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask2) { + delete_block(block); + } + if (block == block->next_2) + fatal("Broken 2\n"); + block = block->next_2; + } +} + +void +codegen_block_init(uint32_t phys_addr) +{ + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; + + if (!page->block[(phys_addr >> 10) & 3]) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + + block_current = (block_current + 1) & BLOCK_MASK; + block = &codeblock[block_current]; + + if (block->valid != 0) { + delete_block(block); + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; + + block->valid = 1; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->pnt = block_current; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = NULL; + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + block->page_mask = 0; + block->flags = 0; + block->status = cpu_cur_status; + + block->was_recompiled = 0; + + recomp_page = block->phys & ~0xfff; + + codeblock_tree_add(block); +} + +void +codegen_block_start_recompile(codeblock_t *block) +{ + page_t *page = &pages[block->phys >> 12]; + uintptr_t rip_rel; + + if (!page->block[(block->phys >> 10) & 3]) + mem_flush_write_page(block->phys, cs + cpu_state.pc); + + block_num = HASH(block->phys); + block_current = block->pnt; + + if (block->pc != cs + cpu_state.pc || block->was_recompiled) + fatal("Recompile to used block!\n"); + + block->status = cpu_cur_status; + + block_pos = BLOCK_GPF_OFFSET; +# ifdef OLD_GPF +# if _WIN64 + addbyte(0x48); /*XOR RCX, RCX*/ + addbyte(0x31); + addbyte(0xc9); + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); +# else + addbyte(0x48); /*XOR RDI, RDI*/ + addbyte(0x31); + addbyte(0xff); + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); +# endif + call(block, (uintptr_t) x86gpf); + while (block_pos < BLOCK_EXIT_OFFSET) + addbyte(0x90); /*NOP*/ +# else + addbyte(0xC6); /*MOVB ABRT_GPF,(abrt)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(ABRT_GPF); + addbyte(0x31); /* xor eax,eax */ + addbyte(0xc0); + addbyte(0x89); /*MOVB eax,(abrt_error)*/ + addbyte(0x85); + rip_rel = ((uintptr_t) &cpu_state) + 128; + rip_rel = ((uintptr_t) & (abrt_error)) - rip_rel; + addlong((uint32_t) rip_rel); +# endif + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x48); /*ADDL $40,%rsp*/ + addbyte(0x83); + addbyte(0xC4); + addbyte(0x28); + addbyte(0x41); /*POP R15*/ + addbyte(0x5f); + addbyte(0x41); /*POP R14*/ + addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); + addbyte(0x5f); /*POP RDI*/ + addbyte(0x5e); /*POP RSI*/ + addbyte(0x5d); /*POP RBP*/ + addbyte(0x5b); /*POP RDX*/ + addbyte(0xC3); /*RET*/ + cpu_block_end = 0; + block_pos = 0; /*Entry code*/ + addbyte(0x53); /*PUSH RBX*/ + addbyte(0x55); /*PUSH RBP*/ + addbyte(0x56); /*PUSH RSI*/ + addbyte(0x57); /*PUSH RDI*/ + addbyte(0x41); /*PUSH R12*/ + addbyte(0x54); + addbyte(0x41); /*PUSH R13*/ + addbyte(0x55); + addbyte(0x41); /*PUSH R14*/ + addbyte(0x56); + addbyte(0x41); /*PUSH R15*/ + addbyte(0x57); + addbyte(0x48); /*SUBL $40,%rsp*/ + addbyte(0x83); + addbyte(0xEC); + addbyte(0x28); + addbyte(0x48); /*MOVL RBP, &cpu_state*/ + addbyte(0xBD); + addquad(((uintptr_t) &cpu_state) + 128); + + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; + + codegen_block_cycles = 0; + codegen_timing_block_start(); + + codegen_block_ins = 0; + codegen_block_full_ins = 0; + + recomp_page = block->phys & ~0xfff; + + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; + + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + + codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; + + block->was_recompiled = 1; + + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); +} + +void +codegen_block_remove(void) +{ + codeblock_t *block = &codeblock[block_current]; + + delete_block(block); + + recomp_page = -1; +} + +void +codegen_block_generate_end_mask(void) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + + block->endpc = codegen_endpc; + + block->page_mask = 0; + start_pc = (block->pc & 0x3ff) & ~15; + if ((block->pc ^ block->endpc) & ~0x3ff) + end_pc = 0x3ff & ~15; + else + end_pc = (block->endpc & 0x3ff) & ~15; + if (end_pc < start_pc) + end_pc = 0x3ff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; + + for (; start_pc <= end_pc; start_pc++) + block->page_mask |= ((uint64_t) 1 << start_pc); + + pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = NULL; + if ((block->pc ^ block->endpc) & ~0x3ff) { + block->phys_2 = get_phys_noabrt(block->endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; + + start_pc = 0; + end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t) 1 << start_pc); + page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; + + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) + mem_flush_write_page(block->phys_2, block->endpc); + + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (block->next_2->valid == 0) + fatal("block->next_2->valid=0 %p\n", (void *) block->next_2); + } + + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + } + } + + recomp_page = -1; +} + +void +codegen_block_end(void) +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void +codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + + codegen_accumulate_flush(); + + addbyte(0x48); /*ADDL $40,%rsp*/ + addbyte(0x83); + addbyte(0xC4); + addbyte(0x28); + addbyte(0x41); /*POP R15*/ + addbyte(0x5f); + addbyte(0x41); /*POP R14*/ + addbyte(0x5e); + addbyte(0x41); /*POP R13*/ + addbyte(0x5d); + addbyte(0x41); /*POP R12*/ + addbyte(0x5c); + addbyte(0x5f); /*POP RDI*/ + addbyte(0x5e); /*POP RSI*/ + addbyte(0x5d); /*POP RBP*/ + addbyte(0x5b); /*POP RDX*/ + addbyte(0xC3); /*RET*/ + + if (block_pos > BLOCK_GPF_OFFSET) + fatal("Over limit!\n"); + + remove_from_block_list(block, block->pc); + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void +codegen_flush(void) +{ + return; +} + +static int opcode_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ +}; +int opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + + 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ +}; + +void +codegen_debug(void) +{ +} + +static x86seg * +codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + if (!cpu_mod && cpu_rm == 6) { + addbyte(0xC7); /*MOVL $0,(ssegs)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + int base_reg = 0, index_reg = 0; + + switch (cpu_rm) { + case 0: + case 1: + case 7: + base_reg = LOAD_REG_W(REG_BX); + break; + case 2: + case 3: + case 6: + base_reg = LOAD_REG_W(REG_BP); + break; + case 4: + base_reg = LOAD_REG_W(REG_SI); + break; + case 5: + base_reg = LOAD_REG_W(REG_DI); + break; + } + if (!(cpu_rm & 4)) { + if (cpu_rm & 1) + index_reg = LOAD_REG_W(REG_DI); + else + index_reg = LOAD_REG_W(REG_SI); + } + base_reg &= 7; + index_reg &= 7; + + switch (cpu_mod) { + case 0: + if (cpu_rm & 4) { + addbyte(0x41); /*MOVZX EAX, base_reg*/ + addbyte(0x0f); + addbyte(0xb7); + addbyte(0xc0 | base_reg); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3)); + } + } + break; + case 1: + if (cpu_rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm8*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3)); + addbyte((fetchdat >> 8) & 0xff); + } (*op_pc)++; - - if (cpu_mod || (sib & 7) != 5) - base_reg = LOAD_REG_L(sib & 7) & 7; - - if (((sib >> 3) & 7) != 4) - index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; - - if (index_reg == -1) - { - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOV EAX, imm32*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x44); /*MOV EAX, base_reg*/ - addbyte(0x89); - addbyte(0xc0 | (base_reg << 3)); - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x44); - addbyte(0x24); - } - else - { - addbyte(0x40 | base_reg); - } - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg*/ - addbyte(0x41); - addbyte(0x8d); - if (base_reg == 4) - { - addbyte(0x84); - addbyte(0x24); - } - else - { - addbyte(0x80 | base_reg); - } - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } + break; + case 2: + if (cpu_rm & 4) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong((fetchdat >> 8) & 0xffff); + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg+imm16*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3)); + addlong((fetchdat >> 8) & 0xffff); } - else - { - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - if (sib >> 6) - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ - addbyte(0x42); - addbyte(0x8d); - addbyte(0x04); - addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); - addlong(new_eaaddr); - } - else - { - addbyte(0x67); /*LEA EAX, imm32+index_reg*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | index_reg); - addlong(new_eaaddr); - } - (*op_pc) += 4; - } - else - { - addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - if (base_reg == 5) - { - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte(0); - } - else - { - addbyte(0x04); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - } - } - break; - case 1: - addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x44); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addbyte((fetchdat >> 16) & 0xff); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ - addbyte(0x43); - addbyte(0x8d); - addbyte(0x84); - addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); - addlong(new_eaaddr); - (*op_pc) += 4; - break; - } - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); + (*op_pc) += 2; + break; } - else - { - int base_reg; + if (cpu_mod || !(cpu_rm & 4)) { + addbyte(0x25); /*ANDL $0xffff, %eax*/ + addlong(0xffff); + } + addbyte(0x89); /*MOV eaaddr, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); - if (!cpu_mod && cpu_rm == 5) - { + if (mod1seg[cpu_rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; +} +// #if 0 +static x86seg * +codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +{ + uint32_t new_eaaddr; + + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + int base_reg = -1, index_reg = -1; + + (*op_pc)++; + + if (cpu_mod || (sib & 7) != 5) + base_reg = LOAD_REG_L(sib & 7) & 7; + + if (((sib >> 3) & 7) != 4) + index_reg = LOAD_REG_L((sib >> 3) & 7) & 7; + + if (index_reg == -1) { + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); + addbyte(0xb8); /*MOV EAX, imm32*/ addlong(new_eaaddr); (*op_pc) += 4; - return op_ea_seg; - } - base_reg = LOAD_REG_L(cpu_rm) & 7; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) - { - addbyte(0x67); /*LEA EAX, base_reg+imm8*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x40 | base_reg); - addbyte((fetchdat >> 8) & 0xff); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x67); /*LEA EAX, base_reg+imm32*/ - addbyte(0x41); - addbyte(0x8d); - addbyte(0x80 | base_reg); - addlong(new_eaaddr); - (*op_pc) += 4; - } - addbyte(0x89); /*MOV eaaddr, EAX*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } - else - { - addbyte(0x44); /*MOV eaaddr, base_reg*/ + } else { + addbyte(0x44); /*MOV EAX, base_reg*/ addbyte(0x89); - addbyte(0x45 | (base_reg << 3)); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - } + addbyte(0xc0 | (base_reg << 3)); + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x44); + addbyte(0x24); + } else { + addbyte(0x40 | base_reg); + } + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg*/ + addbyte(0x41); + addbyte(0x8d); + if (base_reg == 4) { + addbyte(0x84); + addbyte(0x24); + } else { + addbyte(0x80 | base_reg); + } + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } + } else { + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + if (sib >> 6) { + addbyte(0x67); /*LEA EAX, imm32+index_reg*scale*/ + addbyte(0x42); + addbyte(0x8d); + addbyte(0x04); + addbyte(0x05 | (sib & 0xc0) | (index_reg << 3)); + addlong(new_eaaddr); + } else { + addbyte(0x67); /*LEA EAX, imm32+index_reg*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | index_reg); + addlong(new_eaaddr); + } + (*op_pc) += 4; + } else { + addbyte(0x67); /*LEA EAX, base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + if (base_reg == 5) { + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte(0); + } else { + addbyte(0x04); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + } + } + break; + case 1: + addbyte(0x67); /*LEA EAX, imm8+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x44); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addbyte((fetchdat >> 16) & 0xff); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, imm32+base_reg+index_reg*scale*/ + addbyte(0x43); + addbyte(0x8d); + addbyte(0x84); + addbyte(base_reg | (index_reg << 3) | (sib & 0xc0)); + addlong(new_eaaddr); + (*op_pc) += 4; + break; + } } - return op_ea_seg; -} -//#endif -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - const OpFn *op_table = (OpFn *) x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; - - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; - op_old_pc = old_pc; - - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - op_pc++; + addbyte(0x05); + addlong(stack_offset); } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + + addbyte(0x89); /*MOV eaaddr, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + } else { + int base_reg; + + if (!cpu_mod && cpu_rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + base_reg = LOAD_REG_L(cpu_rm) & 7; + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + addbyte(0x67); /*LEA EAX, base_reg+imm8*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x40 | base_reg); + addbyte((fetchdat >> 8) & 0xff); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x67); /*LEA EAX, base_reg+imm32*/ + addbyte(0x41); + addbyte(0x8d); + addbyte(0x80 | base_reg); + addlong(new_eaaddr); + (*op_pc) += 4; + } + addbyte(0x89); /*MOV eaaddr, EAX*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + } else { + addbyte(0x44); /*MOV eaaddr, base_reg*/ + addbyte(0x89); + addbyte(0x45 | (base_reg << 3)); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + } + } + return op_ea_seg; +} +// #endif +void +codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t op_32 = use32; + uint32_t op_pc = new_pc; + const OpFn *op_table = (OpFn *) x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + int over = 0; + int pc_off = 0; + int test_modrm = 1; + int c; + + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; + op_old_pc = old_pc; + + for (c = 0; c < NR_HOST_REGS; c++) + host_reg_mapping[c] = -1; + for (c = 0; c < NR_HOST_XMM_REGS; c++) + host_reg_xmm_mapping[c] = -1; + + codegen_timing_start(); + + while (!over) { + switch (opcode) { + case 0x0f: + op_table = x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; + + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.seg_gs; + op_ssegs = 1; + break; + + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; + + case 0xd8: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; + recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; + recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; + recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; + recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; + recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; + recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; + recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; + recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + + case 0xf0: /*LOCK*/ + break; + + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = recomp_opcodes_REPE; + break; + + default: + goto generate_call; + } + fetchdat = fastreadl(cs + op_pc); + codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; + if (!pc_off) + fetchdat >>= 8; + op_pc++; + } generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = 0; + if ((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = 0; - if (codegen_timing_jump_cycles != NULL) - jump_cycles = codegen_timing_jump_cycles(); - - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, jump_cycles); - } - - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } - - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); - - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; - -#ifdef CHECK_INT - /* Check for interrupts. */ - addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &pic_pending); - addbyte(0x01); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); -#endif - - return; - } - } - - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (op_ssegs != last_ssegs) - { - last_ssegs = op_ssegs; - addbyte(0xC6); /*MOVB $0,(ssegs)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_ssegs); - } - if ((!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); - addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - if (op_ea_seg != last_ea_seg) - { - addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)(uintptr_t)op_ea_seg); - } + if (codegen_timing_jump_cycles != NULL) + jump_cycles = codegen_timing_jump_cycles(); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, -jump_cycles); codegen_accumulate_flush(); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, jump_cycles); + } - addbyte(0xC7); /*MOVL [pc],new_pc*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); - addlong(op_pc + pc_off); - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); + if (new_pc) { + if (new_pc != -1) + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, new_pc); + + codegen_block_ins++; + block->ins++; + codegen_block_full_ins++; + codegen_endpc = (cs + cpu_state.pc) + 8; + +# ifdef CHECK_INT + /* Check for interrupts. */ + addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &pic_pending); + addbyte(0x01); + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) (uintptr_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (uintptr_t) (&block->data[block_pos + 4])); +# endif + + return; } + } - load_param_1_32(block, fetchdat); - call(block, (uintptr_t)op); + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (op_ssegs != last_ssegs) { + last_ssegs = op_ssegs; + addbyte(0xC6); /*MOVB $0,(ssegs)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ssegs)); + addbyte(op_ssegs); + } + if ((!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) /* && !(op_32 & 0x200)*/) { + int stack_offset = 0; - codegen_block_ins++; + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; - block->ins++; + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; -#ifdef CHECK_INT - /* Check for interrupts. */ - addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t) (uintptr_t) &pic_pending); -#endif + addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(rm_data.rm_mod_reg_data)); + addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - addbyte(0x85); /*OR %eax, %eax*/ - addbyte(0xc0); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)(uintptr_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(uintptr_t)(&block->data[block_pos + 4])); + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); + if (cpu_mod != 3 && (op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); + op_pc -= pc_off; + } + if (op_ea_seg != last_ea_seg) { + addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ea_seg)); + addlong((uint32_t) (uintptr_t) op_ea_seg); + } - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_accumulate_flush(); + + addbyte(0xC7); /*MOVL [pc],new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); + addlong(op_pc + pc_off); + addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(old_pc); + if (op_32 != last_op32) { + last_op32 = op_32; + addbyte(0xC7); /*MOVL $use32,(op32)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(op32)); + addlong(op_32); + } + + load_param_1_32(block, fetchdat); + call(block, (uintptr_t) op); + + codegen_block_ins++; + + block->ins++; + +# ifdef CHECK_INT + /* Check for interrupts. */ + addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ + addbyte(0x04); + addbyte(0x25); + addlong((uint32_t) (uintptr_t) &pic_pending); +# endif + + addbyte(0x85); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) (uintptr_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (uintptr_t) (&block->data[block_pos + 4])); + + codegen_endpc = (cs + cpu_state.pc) + 8; } #endif diff --git a/src/codegen/codegen_x86-64.h b/src/codegen/codegen_x86-64.h index 1ef81ff89..91c10a9ee 100644 --- a/src/codegen/codegen_x86-64.h +++ b/src/codegen/codegen_x86-64.h @@ -1,24 +1,23 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) #define BLOCK_EXIT_OFFSET 0x7e0 #ifdef OLD_GPF -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) #else -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 12) #endif #define BLOCK_MAX 1620 -enum -{ - OP_RET = 0xc3 +enum { + OP_RET = 0xc3 }; #define NR_HOST_REGS 4 diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index fe4703ea7..61b473fe7 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -38,2139 +38,2127 @@ */ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include -#include -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> -#include "x86.h" -#include "x86_flags.h" -#include "x86_ops.h" -#include "x87.h" +# include +# include +# include +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> +# include "x86.h" +# include "x86_flags.h" +# include "x86_ops.h" +# include "x87.h" /*ex*/ -#include <86box/nmi.h> -#include <86box/pic.h> +# include <86box/nmi.h> +# include <86box/pic.h> -#include "386_common.h" +# include "386_common.h" -#include "codegen.h" -#include "codegen_accumulate.h" -#include "codegen_ops.h" -#include "codegen_ops_x86.h" +# include "codegen.h" +# include "codegen_accumulate.h" +# include "codegen_ops.h" +# include "codegen_ops_x86.h" -#ifdef __unix__ -#include -#include -#endif -#if defined _WIN32 -#include -#endif +# ifdef __unix__ +# include +# include +# endif +# if defined _WIN32 +# include +# endif -int codegen_flat_ds, codegen_flat_ss; -int mmx_ebx_ecx_loaded; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_mmx_entered = 0; -int codegen_fpu_loaded_iq[8]; -x86seg *op_ea_seg; -int op_ssegs; +int codegen_flat_ds, codegen_flat_ss; +int mmx_ebx_ecx_loaded; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_mmx_entered = 0; +int codegen_fpu_loaded_iq[8]; +x86seg *op_ea_seg; +int op_ssegs; uint32_t op_old_pc; uint32_t recomp_page = -1; -int host_reg_mapping[NR_HOST_REGS]; -int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; -codeblock_t *codeblock; +int host_reg_mapping[NR_HOST_REGS]; +int host_reg_xmm_mapping[NR_HOST_XMM_REGS]; +codeblock_t *codeblock; codeblock_t **codeblock_hash; - -int block_current = 0; +int block_current = 0; static int block_num; -int block_pos; +int block_pos; uint32_t codegen_endpc; -int codegen_block_cycles; +int codegen_block_cycles; static int codegen_block_ins; static int codegen_block_full_ins; static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; +static x86seg *last_ea_seg; +static int last_ssegs; static uint32_t mem_abrt_rout; -uint32_t mem_load_addr_ea_b; -uint32_t mem_load_addr_ea_w; -uint32_t mem_load_addr_ea_l; -uint32_t mem_load_addr_ea_q; -uint32_t mem_store_addr_ea_b; -uint32_t mem_store_addr_ea_w; -uint32_t mem_store_addr_ea_l; -uint32_t mem_store_addr_ea_q; -uint32_t mem_load_addr_ea_b_no_abrt; -uint32_t mem_store_addr_ea_b_no_abrt; -uint32_t mem_load_addr_ea_w_no_abrt; -uint32_t mem_store_addr_ea_w_no_abrt; -uint32_t mem_load_addr_ea_l_no_abrt; -uint32_t mem_store_addr_ea_l_no_abrt; -uint32_t mem_check_write; -uint32_t mem_check_write_w; -uint32_t mem_check_write_l; +uint32_t mem_load_addr_ea_b; +uint32_t mem_load_addr_ea_w; +uint32_t mem_load_addr_ea_l; +uint32_t mem_load_addr_ea_q; +uint32_t mem_store_addr_ea_b; +uint32_t mem_store_addr_ea_w; +uint32_t mem_store_addr_ea_l; +uint32_t mem_store_addr_ea_q; +uint32_t mem_load_addr_ea_b_no_abrt; +uint32_t mem_store_addr_ea_b_no_abrt; +uint32_t mem_load_addr_ea_w_no_abrt; +uint32_t mem_store_addr_ea_w_no_abrt; +uint32_t mem_load_addr_ea_l_no_abrt; +uint32_t mem_store_addr_ea_l_no_abrt; +uint32_t mem_check_write; +uint32_t mem_check_write_w; +uint32_t mem_check_write_l; -static uint32_t gen_MEM_LOAD_ADDR_EA_B(void) +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) -{ -#ifdef _WIN32 - codeblock = VirtualAlloc(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); -#elif defined __unix__ - codeblock = mmap(NULL, (BLOCK_SIZE+1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); -#else - codeblock = malloc((BLOCK_SIZE+1) * sizeof(codeblock_t)); -#endif - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - - memset(codeblock, 0, (BLOCK_SIZE+1) * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - - block_current = BLOCK_SIZE; - block_pos = 0; - mem_abrt_rout = (uint32_t)&codeblock[block_current].data[block_pos]; - addbyte(0x83); /*ADDL $16+4,%esp*/ - addbyte(0xC4); - addbyte(0x10+4); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l = (uint32_t)gen_MEM_LOAD_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w = (uint32_t)gen_MEM_LOAD_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b = (uint32_t)gen_MEM_LOAD_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_q = (uint32_t)gen_MEM_LOAD_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l = (uint32_t)gen_MEM_STORE_ADDR_EA_L(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w = (uint32_t)gen_MEM_STORE_ADDR_EA_W(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b = (uint32_t)gen_MEM_STORE_ADDR_EA_B(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_q = (uint32_t)gen_MEM_STORE_ADDR_EA_Q(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); - block_pos = (block_pos + 15) & ~15; - mem_check_write = (uint32_t)gen_MEM_CHECK_WRITE(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_w = (uint32_t)gen_MEM_CHECK_WRITE_W(); - block_pos = (block_pos + 15) & ~15; - mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L(); - -#ifndef _MSC_VER - asm( - "fstcw %0\n" - : "=m" (cpu_state.old_npxc) - ); -#else - __asm - { - fstcw cpu_state.old_npxc - } -#endif -} - -void codegen_reset(void) -{ - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - mem_reset_page_blocks(); -} - -void dump_block(void) -{ -} - -static void add_to_block_list(codeblock_t *block) -{ - codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; - - if (!block->page_mask) - fatal("add_to_block_list - mask = 0\n"); - - if (block_prev) - { - block->next = block_prev; - block_prev->prev = block; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - else - { - block->next = NULL; - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; - } - - if (block->next) - { - if (!block->next->valid) - fatal("block->next->valid=0 %p %p %x %x\n", (void *)block->next, (void *)codeblock, block_current, block_pos); - } - - if (block->page_mask2) - { - block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; - - if (block_prev) - { - block->next_2 = block_prev; - block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - else - { - block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; - } - } -} - -static void remove_from_block_list(codeblock_t *block, uint32_t pc) -{ - if (!block->page_mask) - return; - - if (block->prev) - { - block->prev->next = block->next; - if (block->next) - block->next->prev = block->prev; - } - else - { - pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; - if (block->next) - block->next->prev = NULL; - else - mem_flush_write_page(block->phys, 0); - } - if (!block->page_mask2) - { - if (block->prev_2 || block->next_2) - fatal("Invalid block_2\n"); - return; - } - - if (block->prev_2) - { - block->prev_2->next_2 = block->next_2; - if (block->next_2) - block->next_2->prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; - if (block->next_2) - block->next_2->prev_2 = NULL; - else - mem_flush_write_page(block->phys_2, 0); - } -} - -static void delete_block(codeblock_t *block) -{ - uint32_t old_pc = block->pc; - - if (block == codeblock_hash[HASH(block->phys)]) - codeblock_hash[HASH(block->phys)] = NULL; - - if (!block->valid) - fatal("Deleting deleted block\n"); - block->valid = 0; - - codeblock_tree_delete(block); - remove_from_block_list(block, old_pc); -} - -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) -{ - struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask) - { - delete_block(block); - } - if (block == block->next) - fatal("Broken 1\n"); - block = block->next; - } - - block = page->block_2[(phys_addr >> 10) & 3]; - - while (block) - { - if (mask & block->page_mask2) - { - delete_block(block); - } - if (block == block->next_2) - fatal("Broken 2\n"); - block = block->next_2; - } -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block[(phys_addr >> 10) & 3]) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - - block_current = (block_current + 1) & BLOCK_MASK; - block = &codeblock[block_current]; - - if (block->valid != 0) - { - delete_block(block); - } - block_num = HASH(phys_addr); - codeblock_hash[block_num] = &codeblock[block_current]; - - block->valid = 1; - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->pnt = block_current; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - block->dirty_mask2 = NULL; - block->next = block->prev = NULL; - block->next_2 = block->prev_2 = NULL; - block->page_mask = 0; - block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; - - block->was_recompiled = 0; - - recomp_page = block->phys & ~0xfff; - - codeblock_tree_add(block); -} - -void codegen_block_start_recompile(codeblock_t *block) -{ - page_t *page = &pages[block->phys >> 12]; - - if (!page->block[(block->phys >> 10) & 3]) - mem_flush_write_page(block->phys, cs+cpu_state.pc); - - block_num = HASH(block->phys); - block_current = block->pnt; - - if (block->pc != cs + cpu_state.pc || block->was_recompiled) - fatal("Recompile to used block!\n"); - - block->status = cpu_cur_status; - - block_pos = BLOCK_GPF_OFFSET; -#ifdef OLD_GPF - addbyte(0xc7); /*MOV [ESP],0*/ - addbyte(0x04); - addbyte(0x24); - addlong(0); - addbyte(0xc7); /*MOV [ESP+4],0*/ - addbyte(0x44); - addbyte(0x24); - addbyte(0x04); - addlong(0); - addbyte(0xe8); /*CALL x86gpf*/ - addlong((uint32_t)x86gpf - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); -#else - addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */ - addbyte(0x05); - addlong((uint32_t) (uintptr_t) &(cpu_state.abrt)); - addbyte(ABRT_GPF); - addbyte(0x31); /* xor eax,eax */ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX EAX, B[EDX+EDI]*/ + addbyte(0xb6); + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmembl*/ + addlong((uint32_t) readmembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*MOVZX EAX, AL*/ + addbyte(0xb6); addbyte(0xc0); - addbyte(0xa3); /* mov [&(abrt_error)],eax */ - addlong((uint32_t) (uintptr_t) &(abrt_error)); -#endif - block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ - addbyte(0x83); /*ADDL $16,%esp*/ - addbyte(0xC4); - addbyte(0x10); - addbyte(0x5f); /*POP EDI*/ - addbyte(0x5e); /*POP ESI*/ - addbyte(0x5d); /*POP EBP*/ - addbyte(0x5b); /*POP EDX*/ - addbyte(0xC3); /*RET*/ - cpu_block_end = 0; - block_pos = 0; /*Entry code*/ - addbyte(0x53); /*PUSH EBX*/ - addbyte(0x55); /*PUSH EBP*/ - addbyte(0x56); /*PUSH ESI*/ - addbyte(0x57); /*PUSH EDI*/ - addbyte(0x83); /*SUBL $16,%esp*/ - addbyte(0xEC); - addbyte(0x10); - addbyte(0xBD); /*MOVL EBP, &cpu_state*/ - addlong(((uintptr_t)&cpu_state) + 128); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; - - codegen_block_cycles = 0; - codegen_timing_block_start(); - - codegen_block_ins = 0; - codegen_block_full_ins = 0; - - recomp_page = block->phys & ~0xfff; - - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; - - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - - block->TOP = cpu_state.TOP & 7; - block->was_recompiled = 1; - - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); - - codegen_accumulate_reset(); + return addr; } -void codegen_block_remove(void) +static uint32_t +gen_MEM_LOAD_ADDR_EA_W(void) { - codeblock_t *block = &codeblock[block_current]; + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; - delete_block(block); + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ + addbyte(0xb7); + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ - recomp_page = -1; + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemwl*/ + addlong((uint32_t) readmemwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*MOVZX EAX, AX*/ + addbyte(0xb7); + addbyte(0xc0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; } -void codegen_block_generate_end_mask(void) +static uint32_t +gen_MEM_LOAD_ADDR_EA_L(void) { - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; - block->endpc = codegen_endpc; + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ - block->page_mask = 0; - start_pc = (block->pc & 0x3ff) & ~15; - if ((block->pc ^ block->endpc) & ~0x3ff) - end_pc = 0x3ff & ~15; - else - end_pc = (block->endpc & 0x3ff) & ~15; - if (end_pc < start_pc) - end_pc = 0x3ff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemll*/ + addlong((uint32_t) readmemll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ - for (; start_pc <= end_pc; start_pc++) - { - block->page_mask |= ((uint64_t)1 << start_pc); + return addr; +} + +static uint32_t +gen_MEM_LOAD_ADDR_EA_Q(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 4 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 4 + 1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); + addbyte(0x3a); + addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ + addbyte(0x54); + addbyte(0x3a); + addbyte(4); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemql*/ + addlong((uint32_t) readmemql - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_B(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x88); /*MOV [EDI+ESI],CL*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writemembl*/ + addlong((uint32_t) writemembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_W(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ + addbyte(0x89); + addbyte(0x04 | (REG_CX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememwl*/ + addlong((uint32_t) writememwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_L(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememll*/ + addlong((uint32_t) writememll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_STORE_ADDR_EA_Q(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = EBX/ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EDX, ESI*/ + addbyte(0xf2); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 7*/ + addbyte(0xc7); + addlong(7); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 4 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 4 + 1); + addbyte(0x89); /*MOV [EDI+ESI],EBX*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(4); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0x01); /*ADD EDX,EAX*/ + addbyte(0xC2); + addbyte(0x52); /*PUSH EDX*/ + addbyte(0xe8); /*CALL writememql*/ + addlong((uint32_t) writememql - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 12*/ + addbyte(0xc4); + addbyte(12); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX ECX, B[EDX+EDI]*/ + addbyte(0xb6); + addbyte(0x0c); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmembl*/ + addlong((uint32_t) readmembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); +# endif + addbyte(0x0f); /*MOVZX ECX, AL*/ + addbyte(0xb6); + addbyte(0xc8); +# ifndef RELEASE_BUILD + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ + addbyte(0xb7); + addbyte(0x0c); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemwl*/ + addlong((uint32_t) readmemwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); +# endif + addbyte(0x0f); /*MOVZX ECX, AX*/ + addbyte(0xb7); + addbyte(0xc8); +# ifndef RELEASE_BUILD + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t) readlookup2); + addbyte(0x75); /*JE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ + addbyte(0x0c); + addbyte(0x3a); + addbyte(0xc3); /*RET*/ + + addbyte(0x01); /*slowpath: ADD ESI,EAX*/ + addbyte(0xc6); + addbyte(0x56); /*PUSH ESI*/ + addbyte(0xe8); /*CALL readmemll*/ + addlong((uint32_t) readmemll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x89); /*MOV ECX, EAX*/ + addbyte(0xc1); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0x83); /*SUBL 4,%esp*/ + addbyte(0xEC); + addbyte(4); + addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_STORE_ADDR_EA_B_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x88); /*MOV [EDI+ESI],CL*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xc3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writemembl*/ + addlong((uint32_t) writemembl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_STORE_ADDR_EA_W_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 1*/ + addbyte(0xc7); + addlong(1); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 4 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(4 + 1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ + addbyte(0x89); + addbyte(0x04 | (REG_CX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememwl*/ + addlong((uint32_t) writememwl - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +# ifndef RELEASE_BUILD +static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; +# endif +static uint32_t +gen_MEM_STORE_ADDR_EA_L_NO_ABRT(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*dat = ECX, seg = ESI, addr = EAX*/ + addbyte(0x89); /*MOV EBX, ESI*/ + addbyte(0xf3); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 3*/ + addbyte(0xc7); + addlong(3); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t) writelookup2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3 + 2 + 3 + 1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3 + 1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0xc3); /*RET*/ + + addbyte(0x51); /*slowpath: PUSH ECX*/ + addbyte(0x01); /*ADD EBX,EAX*/ + addbyte(0xC3); + addbyte(0x53); /*PUSH EBX*/ + addbyte(0xe8); /*CALL writememll*/ + addlong((uint32_t) writememll - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); +# ifndef RELEASE_BUILD + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x75); /*JNE mem_abrt_rout*/ + addbyte(1); +# endif + addbyte(0xc3); /*RET*/ +# ifndef RELEASE_BUILD + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err*/ + addbyte(0x04); + addbyte(0x24); + addlong((uint32_t) gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err); + addbyte(0xe8); /*CALL fatal*/ + addlong((uint32_t) fatal - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + /*Should not return!*/ +# endif + return addr; +} + +static uint32_t +gen_MEM_CHECK_WRITE(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*seg = ESI, addr = EAX*/ + + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3d); + addlong((uint32_t) &cr0); + addbyte(0); + addbyte(0x78); /*JS +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(11); + addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ + addbyte(0x3c); + addbyte(0xbd); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + + /*slowpath:*/ + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x6a); /*PUSH 1*/ + addbyte(1); + addbyte(0x57); /*PUSH EDI*/ + addbyte(0xe8); /*CALL mmutranslatereal32*/ + addlong((uint32_t) mmutranslatereal32 - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*ADD ESP, 8*/ + addbyte(0xc4); + addbyte(8); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_CHECK_WRITE_W(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*seg = ESI, addr = EAX*/ + + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3d); + addlong((uint32_t) &cr0); + addbyte(0); + addbyte(0x78); /*JS +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x8d); /*LEA ESI, 1[EDI]*/ + addbyte(0x77); + addbyte(0x01); + addbyte(0x74); /*JE slowpath*/ + addbyte(11); + addbyte(0x89); /*MOV EAX, EDI*/ + addbyte(0xf8); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ + addbyte(0x3c); + addbyte(0xbd); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(11); + addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ + addbyte(0x3c); + addbyte(0xb5); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + + /*slowpath:*/ + addbyte(0x89); /*MOV EDI, EAX*/ + addbyte(0xc7); + /*slowpath_lp:*/ + addbyte(0x6a); /*PUSH 1*/ + addbyte(1); + addbyte(0x57); /*PUSH EDI*/ + addbyte(0xe8); /*CALL mmutranslatereal32*/ + addlong((uint32_t) mmutranslatereal32 - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x83); /*ADD EDI, 1*/ + addbyte(0xc7); + addbyte(1); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST $fff, EDI*/ + addbyte(0xc7); + addlong(0xfff); + addbyte(0x74); /*JE slowpath_lp*/ + addbyte(-33); + addbyte(0xc3); /*RET*/ + + return addr; +} + +static uint32_t +gen_MEM_CHECK_WRITE_L(void) +{ + uint32_t addr = (uint32_t) &codeblock[block_current].data[block_pos]; + + /*seg = ESI, addr = EAX*/ + + addbyte(0x8d); /*LEA EDI, [EAX+ESI]*/ + addbyte(0x3c); + addbyte(0x30); + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3d); + addlong((uint32_t) &cr0); + addbyte(0); + addbyte(0x78); /*JS +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x8d); /*LEA ESI, 3[EDI]*/ + addbyte(0x77); + addbyte(0x03); + addbyte(0x74); /*JE slowpath*/ + addbyte(11); + addbyte(0x89); /*MOV EAX, EDI*/ + addbyte(0xf8); + addbyte(0xc1); /*SHR EDI, 12*/ + addbyte(0xef); + addbyte(12); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xee); + addbyte(12); + addbyte(0x83); /*CMP writelookup2[EDI*4],-1*/ + addbyte(0x3c); + addbyte(0xbd); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(11); + addbyte(0x83); /*CMP writelookup2[ESI*4],-1*/ + addbyte(0x3c); + addbyte(0xb5); + addlong((uint32_t) writelookup2); + addbyte(-1); + addbyte(0x74); /*JE +*/ + addbyte(1); + addbyte(0xc3); /*RET*/ + + /*slowpath:*/ + addbyte(0x89); /*MOV EDI, EAX*/ + addbyte(0xc7); + /*slowpath_lp:*/ + addbyte(0x6a); /*PUSH 1*/ + addbyte(1); + addbyte(0x57); /*PUSH EDI*/ + addbyte(0xe8); /*CALL mmutranslatereal32*/ + addlong((uint32_t) mmutranslatereal32 - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x83); /*ADD ESP, 4*/ + addbyte(0xc4); + addbyte(4); + addbyte(0x83); /*ADD EDI, 3*/ + addbyte(0xc7); + addbyte(3); + addbyte(0x80); /*CMP abrt, 0*/ + addbyte(0x7d); + addbyte((uint8_t) cpu_state_offset(abrt)); + addbyte(0); + addbyte(0x0f); /*JNE mem_abrt_rout*/ + addbyte(0x85); + addlong(mem_abrt_rout - ((uint32_t) (&codeblock[block_current].data[block_pos]) + 4)); + /*If bits 2-11 of the address are now 0 then this crosses a page, so loop back*/ + addbyte(0xf7); /*TEST EDI, FFC*/ + addbyte(0xc7); + addlong(0xffc); + addbyte(0x74); /*JE slowpath_lp*/ + addbyte(-33); + addbyte(0xc3); /*RET*/ + + return addr; +} + +void +codegen_init(void) +{ +# ifdef _WIN32 + codeblock = VirtualAlloc(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), MEM_COMMIT, PAGE_EXECUTE_READWRITE); +# elif defined __unix__ + codeblock = mmap(NULL, (BLOCK_SIZE + 1) * sizeof(codeblock_t), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, 0, 0); +# else + codeblock = malloc((BLOCK_SIZE + 1) * sizeof(codeblock_t)); +# endif + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + + memset(codeblock, 0, (BLOCK_SIZE + 1) * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + + block_current = BLOCK_SIZE; + block_pos = 0; + mem_abrt_rout = (uint32_t) &codeblock[block_current].data[block_pos]; + addbyte(0x83); /*ADDL $16+4,%esp*/ + addbyte(0xC4); + addbyte(0x10 + 4); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_l = (uint32_t) gen_MEM_LOAD_ADDR_EA_L(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_w = (uint32_t) gen_MEM_LOAD_ADDR_EA_W(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_b = (uint32_t) gen_MEM_LOAD_ADDR_EA_B(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_q = (uint32_t) gen_MEM_LOAD_ADDR_EA_Q(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_l = (uint32_t) gen_MEM_STORE_ADDR_EA_L(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_w = (uint32_t) gen_MEM_STORE_ADDR_EA_W(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_b = (uint32_t) gen_MEM_STORE_ADDR_EA_B(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_q = (uint32_t) gen_MEM_STORE_ADDR_EA_Q(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_b_no_abrt = (uint32_t) gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_b_no_abrt = (uint32_t) gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_w_no_abrt = (uint32_t) gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_w_no_abrt = (uint32_t) gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_load_addr_ea_l_no_abrt = (uint32_t) gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_store_addr_ea_l_no_abrt = (uint32_t) gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); + block_pos = (block_pos + 15) & ~15; + mem_check_write = (uint32_t) gen_MEM_CHECK_WRITE(); + block_pos = (block_pos + 15) & ~15; + mem_check_write_w = (uint32_t) gen_MEM_CHECK_WRITE_W(); + block_pos = (block_pos + 15) & ~15; + mem_check_write_l = (uint32_t) gen_MEM_CHECK_WRITE_L(); + +# ifndef _MSC_VER + asm( + "fstcw %0\n" + : "=m"(cpu_state.old_npxc)); +# else + __asm + { + fstcw cpu_state.old_npxc + } +# endif +} + +void +codegen_reset(void) +{ + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + mem_reset_page_blocks(); +} + +void +dump_block(void) +{ +} + +static void +add_to_block_list(codeblock_t *block) +{ + codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; + + if (!block->page_mask) + fatal("add_to_block_list - mask = 0\n"); + + if (block_prev) { + block->next = block_prev; + block_prev->prev = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } else { + block->next = NULL; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; + } + + if (block->next) { + if (!block->next->valid) + fatal("block->next->valid=0 %p %p %x %x\n", (void *) block->next, (void *) codeblock, block_current, block_pos); + } + + if (block->page_mask2) { + block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; + + if (block_prev) { + block->next_2 = block_prev; + block_prev->prev_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; + } else { + block->next_2 = NULL; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } - - pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; - - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0x3ff) - { - block->phys_2 = get_phys_noabrt(block->endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - start_pc = 0; - end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); - page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - - if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) - mem_flush_write_page(block->phys_2, block->endpc); - - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (!block->next_2->valid) - fatal("block->next_2->valid=0 %p\n", (void *)block->next_2); - } - - block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; - } - } - - recomp_page = -1; + } } -void codegen_block_end(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) +static void +remove_from_block_list(codeblock_t *block, uint32_t pc) { + if (!block->page_mask) return; -} -static int opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ -}; -int opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ -}; - -void codegen_debug(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; - } + if (block->prev) { + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } else { + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; + if (block->next) + block->next->prev = NULL; else - { - switch (cpu_mod) - { - case 0: - addbyte(0xa1); /*MOVL *mod1add[0][cpu_rm], %eax*/ - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - break; - case 1: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((uint32_t)(int8_t)(rmdat >> 8)); - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc)++; - break; - case 2: - addbyte(0xb8); /*MOVL ,%eax*/ - addlong((fetchdat >> 8) & 0xffff); - addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[0][cpu_rm]); - addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ - addbyte(0x05); - addlong((uint32_t)mod1add[1][cpu_rm]); - (*op_pc) += 2; - break; - } - addbyte(0x25); /*ANDL $0xffff, %eax*/ - addlong(0xffff); - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); + mem_flush_write_page(block->phys, 0); + } + if (!block->page_mask2) { + if (block->prev_2 || block->next_2) + fatal("Invalid block_2\n"); + return; + } - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - } - return op_ea_seg; + if (block->prev_2) { + block->prev_2->next_2 = block->next_2; + if (block->next_2) + block->next_2->prev_2 = block->prev_2; + } else { + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; + if (block->next_2) + block->next_2->prev_2 = NULL; + else + mem_flush_write_page(block->phys_2, 0); + } } -static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +static void +delete_block(codeblock_t *block) { - uint32_t new_eaaddr; + uint32_t old_pc = block->pc; - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; + if (block == codeblock_hash[HASH(block->phys)]) + codeblock_hash[HASH(block->phys)] = NULL; + + if (!block->valid) + fatal("Deleting deleted block\n"); + block->valid = 0; + + codeblock_tree_delete(block); + remove_from_block_list(block, old_pc); +} + +void +codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +{ + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask) { + delete_block(block); + } + if (block == block->next) + fatal("Broken 1\n"); + block = block->next; + } + + block = page->block_2[(phys_addr >> 10) & 3]; + + while (block) { + if (mask & block->page_mask2) { + delete_block(block); + } + if (block == block->next_2) + fatal("Broken 2\n"); + block = block->next_2; + } +} + +void +codegen_block_init(uint32_t phys_addr) +{ + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; + + if (!page->block[(phys_addr >> 10) & 3]) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + + block_current = (block_current + 1) & BLOCK_MASK; + block = &codeblock[block_current]; + + if (block->valid != 0) { + delete_block(block); + } + block_num = HASH(phys_addr); + codeblock_hash[block_num] = &codeblock[block_current]; + + block->valid = 1; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->pnt = block_current; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = NULL; + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + block->page_mask = 0; + block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; + + block->was_recompiled = 0; + + recomp_page = block->phys & ~0xfff; + + codeblock_tree_add(block); +} + +void +codegen_block_start_recompile(codeblock_t *block) +{ + page_t *page = &pages[block->phys >> 12]; + + if (!page->block[(block->phys >> 10) & 3]) + mem_flush_write_page(block->phys, cs + cpu_state.pc); + + block_num = HASH(block->phys); + block_current = block->pnt; + + if (block->pc != cs + cpu_state.pc || block->was_recompiled) + fatal("Recompile to used block!\n"); + + block->status = cpu_cur_status; + + block_pos = BLOCK_GPF_OFFSET; +# ifdef OLD_GPF + addbyte(0xc7); /*MOV [ESP],0*/ + addbyte(0x04); + addbyte(0x24); + addlong(0); + addbyte(0xc7); /*MOV [ESP+4],0*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x04); + addlong(0); + addbyte(0xe8); /*CALL x86gpf*/ + addlong((uint32_t) x86gpf - (uint32_t) (&codeblock[block_current].data[block_pos + 4])); +# else + addbyte(0xc6); /* mov byte ptr[&(cpu_state.abrt)],ABRT_GPF */ + addbyte(0x05); + addlong((uint32_t) (uintptr_t) & (cpu_state.abrt)); + addbyte(ABRT_GPF); + addbyte(0x31); /* xor eax,eax */ + addbyte(0xc0); + addbyte(0xa3); /* mov [&(abrt_error)],eax */ + addlong((uint32_t) (uintptr_t) & (abrt_error)); +# endif + block_pos = BLOCK_EXIT_OFFSET; /*Exit code*/ + addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0xC4); + addbyte(0x10); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + cpu_block_end = 0; + block_pos = 0; /*Entry code*/ + addbyte(0x53); /*PUSH EBX*/ + addbyte(0x55); /*PUSH EBP*/ + addbyte(0x56); /*PUSH ESI*/ + addbyte(0x57); /*PUSH EDI*/ + addbyte(0x83); /*SUBL $16,%esp*/ + addbyte(0xEC); + addbyte(0x10); + addbyte(0xBD); /*MOVL EBP, &cpu_state*/ + addlong(((uintptr_t) &cpu_state) + 128); + + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; + + codegen_block_cycles = 0; + codegen_timing_block_start(); + + codegen_block_ins = 0; + codegen_block_full_ins = 0; + + recomp_page = block->phys & ~0xfff; + + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; + + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + + block->TOP = cpu_state.TOP & 7; + block->was_recompiled = 1; + + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + + codegen_accumulate_reset(); +} + +void +codegen_block_remove(void) +{ + codeblock_t *block = &codeblock[block_current]; + + delete_block(block); + + recomp_page = -1; +} + +void +codegen_block_generate_end_mask(void) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + + block->endpc = codegen_endpc; + + block->page_mask = 0; + start_pc = (block->pc & 0x3ff) & ~15; + if ((block->pc ^ block->endpc) & ~0x3ff) + end_pc = 0x3ff & ~15; + else + end_pc = (block->endpc & 0x3ff) & ~15; + if (end_pc < start_pc) + end_pc = 0x3ff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; + + for (; start_pc <= end_pc; start_pc++) { + block->page_mask |= ((uint64_t) 1 << start_pc); + } + + pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; + + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = NULL; + if ((block->pc ^ block->endpc) & ~0x3ff) { + block->phys_2 = get_phys_noabrt(block->endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; + + start_pc = 0; + end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t) 1 << start_pc); + page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; + + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) + mem_flush_write_page(block->phys_2, block->endpc); + + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (!block->next_2->valid) + fatal("block->next_2->valid=0 %p\n", (void *) block->next_2); + } + + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + } + } + + recomp_page = -1; +} + +void +codegen_block_end(void) +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask(); + add_to_block_list(block); +} + +void +codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + + codegen_accumulate_flush(); + + addbyte(0x83); /*ADDL $16,%esp*/ + addbyte(0xC4); + addbyte(0x10); + addbyte(0x5f); /*POP EDI*/ + addbyte(0x5e); /*POP ESI*/ + addbyte(0x5d); /*POP EBP*/ + addbyte(0x5b); /*POP EDX*/ + addbyte(0xC3); /*RET*/ + + if (block_pos > BLOCK_GPF_OFFSET) + fatal("Over limit!\n"); + + remove_from_block_list(block, block->pc); + block->next = block->prev = NULL; + block->next_2 = block->prev_2 = NULL; + codegen_block_generate_end_mask(); + add_to_block_list(block); + + if (!(block->flags & CODEBLOCK_HAS_FPU)) + block->flags &= ~CODEBLOCK_STATIC_TOP; +} + +void +codegen_flush(void) +{ + return; +} + +static int opcode_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ +}; +int opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + + 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ +}; + +void +codegen_debug(void) +{ +} + +static x86seg * +codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +{ + if (!cpu_mod && cpu_rm == 6) { + addbyte(0xC7); /*MOVL $0,(ssegs)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong((fetchdat >> 8) & 0xffff); + (*op_pc) += 2; + } else { + switch (cpu_mod) { + case 0: + addbyte(0xa1); /*MOVL *mod1add[0][cpu_rm], %eax*/ + addlong((uint32_t) mod1add[0][cpu_rm]); + addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][cpu_rm]); + break; + case 1: + addbyte(0xb8); /*MOVL ,%eax*/ + addlong((uint32_t) (int8_t) (rmdat >> 8)); + addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[0][cpu_rm]); + addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][cpu_rm]); (*op_pc)++; + break; + case 2: + addbyte(0xb8); /*MOVL ,%eax*/ + addlong((fetchdat >> 8) & 0xffff); + addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[0][cpu_rm]); + addbyte(0x03); /*ADDL *mod1add[1][cpu_rm], %eax*/ + addbyte(0x05); + addlong((uint32_t) mod1add[1][cpu_rm]); + (*op_pc) += 2; + break; + } + addbyte(0x25); /*ANDL $0xffff, %eax*/ + addlong(0xffff); + addbyte(0xa3); + addlong((uint32_t) &cpu_state.eaaddr); - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL ,%eax*/ - addlong(new_eaaddr); - (*op_pc) += 4; - } - else - { - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - } - break; - case 1: - new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc)++; - break; - case 2: - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ - addlong(new_eaaddr); - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); - (*op_pc) += 4; - break; - } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - addbyte(0x05); - addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); - break; - case 1: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - case 2: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0xC1); addbyte(0xE3); addbyte(2); /*SHL $2,%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - case 3: - addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ - addbyte(0xC1); addbyte(0xE3); addbyte(3); /*SHL $2,%ebx*/ - addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ - break; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - else - { - if (!cpu_mod && cpu_rm == 5) - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(eaaddr)); - addlong(new_eaaddr); - (*op_pc) += 4; - return op_ea_seg; - } - addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(regs[cpu_rm].l)); - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) - { - addbyte(0x05); - addlong((uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - addbyte(0x05); - addlong(new_eaaddr); - (*op_pc) += 4; - } - } - addbyte(0xa3); - addlong((uint32_t)&cpu_state.eaaddr); - } - return op_ea_seg; + if (mod1seg[cpu_rm] == &ss && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + } + return op_ea_seg; } -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +static x86seg * +codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { - codeblock_t *block = &codeblock[block_current]; - uint32_t op_32 = use32; - uint32_t op_pc = new_pc; - const OpFn *op_table = x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - int over = 0; - int pc_off = 0; - int test_modrm = 1; - int c; + uint32_t new_eaaddr; - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; - op_old_pc = old_pc; + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; - for (c = 0; c < NR_HOST_REGS; c++) - host_reg_mapping[c] = -1; - mmx_ebx_ecx_loaded = 0; - for (c = 0; c < NR_HOST_XMM_REGS; c++) - host_reg_xmm_mapping[c] = -1; - - codegen_timing_start(); - - while (!over) - { - switch (opcode) - { - case 0x0f: - op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; - - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; - - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; - - case 0xd8: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: - op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - - case 0xf0: /*LOCK*/ - break; - - case 0xf2: /*REPNE*/ - op_table = x86_dynarec_opcodes_REPNE; - recomp_op_table = recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ - op_table = x86_dynarec_opcodes_REPE; - recomp_op_table = recomp_opcodes_REPE; - break; - - default: - goto generate_call; + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL ,%eax*/ + addlong(new_eaaddr); + (*op_pc) += 4; + } else { + addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - - op_pc++; + break; + case 1: + new_eaaddr = (uint32_t) (int8_t) ((fetchdat >> 16) & 0xff); + addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ + addlong(new_eaaddr); + addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + (*op_pc)++; + break; + case 2: + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xb8); /*MOVL new_eaaddr, %eax*/ + addlong(new_eaaddr); + addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[sib & 7].l)); + (*op_pc) += 4; + break; } + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ + { + addbyte(0x05); + addlong(stack_offset); + } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); + break; + case 1: + addbyte(0x8B); + addbyte(0x5D); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + break; + case 2: + addbyte(0x8B); + addbyte(0x5D); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0xC1); + addbyte(0xE3); + addbyte(2); /*SHL $2,%ebx*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + break; + case 3: + addbyte(0x8B); + addbyte(0x5D); + addbyte((uint8_t) cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0xC1); + addbyte(0xE3); + addbyte(3); /*SHL $2,%ebx*/ + addbyte(0x01); + addbyte(0xD8); /*ADDL %ebx,%eax*/ + break; + } + } + addbyte(0xa3); + addlong((uint32_t) &cpu_state.eaaddr); + } else { + if (!cpu_mod && cpu_rm == 5) { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(eaaddr)); + addlong(new_eaaddr); + (*op_pc) += 4; + return op_ea_seg; + } + addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(regs[cpu_rm].l)); + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + addbyte(0x05); + addlong((uint32_t) (int8_t) (fetchdat >> 8)); + (*op_pc)++; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + addbyte(0x05); + addlong(new_eaaddr); + (*op_pc) += 4; + } + } + addbyte(0xa3); + addlong((uint32_t) &cpu_state.eaaddr); + } + return op_ea_seg; +} + +void +codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +{ + codeblock_t *block = &codeblock[block_current]; + uint32_t op_32 = use32; + uint32_t op_pc = new_pc; + const OpFn *op_table = x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + int over = 0; + int pc_off = 0; + int test_modrm = 1; + int c; + + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; + op_old_pc = old_pc; + + for (c = 0; c < NR_HOST_REGS; c++) + host_reg_mapping[c] = -1; + mmx_ebx_ecx_loaded = 0; + for (c = 0; c < NR_HOST_XMM_REGS; c++) + host_reg_xmm_mapping[c] = -1; + + codegen_timing_start(); + + while (!over) { + switch (opcode) { + case 0x0f: + op_table = x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; + + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.seg_gs; + op_ssegs = 1; + break; + + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; + + case 0xd8: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d8_a32 : x86_dynarec_opcodes_d8_a16; + recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_d9_a32 : x86_dynarec_opcodes_d9_a16; + recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; + recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_db_a32 : x86_dynarec_opcodes_db_a16; + recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dc_a32 : x86_dynarec_opcodes_dc_a16; + recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_dd_a32 : x86_dynarec_opcodes_dd_a16; + recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_de_a32 : x86_dynarec_opcodes_de_a16; + recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: + op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_df_a32 : x86_dynarec_opcodes_df_a16; + recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + + case 0xf0: /*LOCK*/ + break; + + case 0xf2: /*REPNE*/ + op_table = x86_dynarec_opcodes_REPNE; + recomp_op_table = recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ + op_table = x86_dynarec_opcodes_REPE; + recomp_op_table = recomp_opcodes_REPE; + break; + + default: + goto generate_call; + } + fetchdat = fastreadl(cs + op_pc); + codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; + if (!pc_off) + fetchdat >>= 8; + + op_pc++; + } generate_call: - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = 0; + if ((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = 0; if (codegen_timing_jump_cycles != NULL) jump_cycles = codegen_timing_jump_cycles(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(); - if (jump_cycles) - codegen_accumulate(ACCREG_cycles, jump_cycles); - } + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(); + if (jump_cycles) + codegen_accumulate(ACCREG_cycles, jump_cycles); + } - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; - } + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { + op_table = x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } - if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); - if (new_pc) - { - if (new_pc != -1) - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, new_pc); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & 0x1ff](opcode, fetchdat, op_32, op_pc, block); + if (new_pc) { + if (new_pc != -1) + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, new_pc); - codegen_block_ins++; - block->ins++; - codegen_block_full_ins++; - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_block_ins++; + block->ins++; + codegen_block_full_ins++; + codegen_endpc = (cs + cpu_state.pc) + 8; -#ifdef CHECK_INT +# ifdef CHECK_INT /* Check for interrupts. */ - addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ + addbyte(0xf6); /* test byte ptr[&pic_pending],1 */ addbyte(0x05); addlong((uint32_t) (uintptr_t) &pic_pending); addbyte(0x01); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); -#endif + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (&block->data[block_pos + 4])); +# endif - return; - } + return; } + } - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - if (op_ssegs != last_ssegs) - { - last_ssegs = op_ssegs; + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + if (op_ssegs != last_ssegs) { + last_ssegs = op_ssegs; - addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ssegs)); - addbyte(op_pc + pc_off); - } - - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); - addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); - if (cpu_mod != 3 && (op_32 & 0x200)) - op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - op_pc -= pc_off; - } - - if (op_ea_seg != last_ea_seg) - { - last_ea_seg = op_ea_seg; - addbyte(0xC7); /*MOVL $&cpu_state.seg_ds,(ea_seg)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(ea_seg)); - addlong((uint32_t)op_ea_seg); - } - - codegen_accumulate_flush(); - - addbyte(0xC7); /*MOVL pc,new_pc*/ + addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(pc)); + addbyte((uint8_t) cpu_state_offset(ssegs)); + addbyte(op_pc + pc_off); + } + + if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode])) { + int stack_offset = 0; + + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; + + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; + + addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(rm_data.rm_mod_reg_data)); + addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); + + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_16_long(op_ea_seg, fetchdat, op_ssegs, &op_pc); + if (cpu_mod != 3 && (op_32 & 0x200)) + op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); + op_pc -= pc_off; + } + + if (op_ea_seg != last_ea_seg) { + last_ea_seg = op_ea_seg; + addbyte(0xC7); /*MOVL $&cpu_state.seg_ds,(ea_seg)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(ea_seg)); + addlong((uint32_t) op_ea_seg); + } + + codegen_accumulate_flush(); + + addbyte(0xC7); /*MOVL pc,new_pc*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(pc)); addlong(op_pc + pc_off); - addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ + addbyte(0x45); + addbyte((uint8_t) cpu_state_offset(oldpc)); + addlong(old_pc); + + if (op_32 != last_op32) { + last_op32 = op_32; + addbyte(0xC7); /*MOVL $use32,(op32)*/ addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(oldpc)); - addlong(old_pc); + addbyte((uint8_t) cpu_state_offset(op32)); + addlong(op_32); + } - if (op_32 != last_op32) - { - last_op32 = op_32; - addbyte(0xC7); /*MOVL $use32,(op32)*/ - addbyte(0x45); - addbyte((uint8_t)cpu_state_offset(op32)); - addlong(op_32); - } + addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ + addbyte(0x04); + addbyte(0x24); + addlong(fetchdat); - addbyte(0xC7); /*MOVL $fetchdat,(%esp)*/ - addbyte(0x04); - addbyte(0x24); - addlong(fetchdat); + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *) op - (uint8_t *) (&block->data[block_pos + 4]))); - addbyte(0xE8); /*CALL*/ - addlong(((uint8_t *)op - (uint8_t *)(&block->data[block_pos + 4]))); + codegen_block_ins++; - codegen_block_ins++; + block->ins++; - block->ins++; - -#ifdef CHECK_INT +# ifdef CHECK_INT /* Check for interrupts. */ - addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ + addbyte(0x0a); /* or al,byte ptr[&pic_pending] */ addbyte(0x05); addlong((uint32_t) (uintptr_t) &pic_pending); -#endif +# endif - addbyte(0x09); /*OR %eax, %eax*/ - addbyte(0xc0); - addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ - addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); + addbyte(0x09); /*OR %eax, %eax*/ + addbyte(0xc0); + addbyte(0x0F); + addbyte(0x85); /*JNZ 0*/ + addlong((uint32_t) &block->data[BLOCK_EXIT_OFFSET] - (uint32_t) (&block->data[block_pos + 4])); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; } #endif diff --git a/src/codegen/codegen_x86.h b/src/codegen/codegen_x86.h index 369614329..d6842eec1 100644 --- a/src/codegen/codegen_x86.h +++ b/src/codegen/codegen_x86.h @@ -1,24 +1,23 @@ -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff -#define BLOCK_START 0 +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff +#define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) #define BLOCK_EXIT_OFFSET 0x7f0 #ifdef OLD_GPF -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) #else -#define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14) +# define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 14) #endif #define BLOCK_MAX 1720 -enum -{ - OP_RET = 0xc3 +enum { + OP_RET = 0xc3 }; #define NR_HOST_REGS 4 diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index eb3c7f5eb..2f178bc74 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -20,43 +20,43 @@ static struct { - uint32_t pc; - int op_ssegs; - x86seg *op_ea_seg; - uint32_t op_32; - int first_uop; - int TOP; + uint32_t pc; + int op_ssegs; + x86seg *op_ea_seg; + uint32_t op_32; + int first_uop; + int TOP; } codegen_instructions[MAX_INSTRUCTION_COUNT]; -int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) +int +codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP) { - int c; + int c; - for (c = 0; c <= block->ins; c++) - { - if (codegen_instructions[c].pc == pc) - { - *first_instruction = c; - *TOP = codegen_instructions[c].TOP; - return codegen_instructions[c].first_uop; - } + for (c = 0; c <= block->ins; c++) { + if (codegen_instructions[c].pc == pc) { + *first_instruction = c; + *TOP = codegen_instructions[c].TOP; + return codegen_instructions[c].first_uop; } + } - *first_instruction = block->ins; - return -1; + *first_instruction = block->ins; + return -1; } -void codegen_set_loop_start(ir_data_t *ir, int first_instruction) +void +codegen_set_loop_start(ir_data_t *ir, int first_instruction) { - uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); - uop_MOV_PTR(ir, IREG_ea_seg, (void *)codegen_instructions[first_instruction].op_ea_seg); - uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); + uop_MOV_IMM(ir, IREG_op32, codegen_instructions[first_instruction].op_32); + uop_MOV_PTR(ir, IREG_ea_seg, (void *) codegen_instructions[first_instruction].op_ea_seg); + uop_MOV_IMM(ir, IREG_ssegs, codegen_instructions[first_instruction].op_ssegs); } int has_ea; codeblock_t *codeblock; -uint16_t *codeblock_hash; +uint16_t *codeblock_hash; void (*codegen_timing_start)(void); void (*codegen_timing_prefix)(uint8_t prefix, uint32_t fetchdat); @@ -65,714 +65,665 @@ void (*codegen_timing_block_start)(void); void (*codegen_timing_block_end)(void); int (*codegen_timing_jump_cycles)(void); -void codegen_timing_set(codegen_timing_t *timing) +void +codegen_timing_set(codegen_timing_t *timing) { - codegen_timing_start = timing->start; - codegen_timing_prefix = timing->prefix; - codegen_timing_opcode = timing->opcode; - codegen_timing_block_start = timing->block_start; - codegen_timing_block_end = timing->block_end; - codegen_timing_jump_cycles = timing->jump_cycles; + codegen_timing_start = timing->start; + codegen_timing_prefix = timing->prefix; + codegen_timing_opcode = timing->opcode; + codegen_timing_block_start = timing->block_start; + codegen_timing_block_end = timing->block_end; + codegen_timing_jump_cycles = timing->jump_cycles; } int codegen_in_recompile; -static int last_op_ssegs; -static x86seg *last_op_ea_seg; +static int last_op_ssegs; +static x86seg *last_op_ea_seg; static uint32_t last_op_32; -void codegen_generate_reset(void) +void +codegen_generate_reset(void) { - last_op_ssegs = -1; - last_op_ea_seg = NULL; - last_op_32 = -1; - has_ea = 0; + last_op_ssegs = -1; + last_op_ea_seg = NULL; + last_op_32 = -1; + has_ea = 0; } -void codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) +void +codegen_check_seg_read(codeblock_t *block, ir_data_t *ir, x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t) -1, codegen_gpf_rout); - seg->checked = 1; + seg->checked = 1; } -void codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) +void +codegen_check_seg_write(codeblock_t *block, ir_data_t *ir, x86seg *seg) { - /*Segments always valid in real/V86 mode*/ - if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) - return; - /*CS and SS must always be valid*/ - if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) - return; - if (seg->checked) - return; - if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) - return; + /*Segments always valid in real/V86 mode*/ + if (!(cr0 & 1) || (cpu_state.eflags & VM_FLAG)) + return; + /*CS and SS must always be valid*/ + if (seg == &cpu_state.seg_cs || seg == &cpu_state.seg_ss) + return; + if (seg->checked) + return; + if (seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) + return; - uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t)-1, codegen_gpf_rout); + uop_CMP_IMM_JZ(ir, ireg_seg_base(seg), (uint32_t) -1, codegen_gpf_rout); - seg->checked = 1; + seg->checked = 1; } -static x86seg *codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +static x86seg * +codegen_generate_ea_16_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { - uint32_t old_pc = (*op_pc) + 1; - if (!cpu_mod && cpu_rm == 6) - { - uint16_t addr = (fetchdat >> 8) & 0xffff; - uop_MOV_IMM(ir, IREG_eaaddr, addr); - (*op_pc) += 2; + uint32_t old_pc = (*op_pc) + 1; + if (!cpu_mod && cpu_rm == 6) { + uint16_t addr = (fetchdat >> 8) & 0xffff; + uop_MOV_IMM(ir, IREG_eaaddr, addr); + (*op_pc) += 2; + } else { + int base_reg, index_reg, offset; + + switch (cpu_rm & 7) { + case 0: + case 1: + case 7: + default: + base_reg = IREG_EBX; + break; + case 2: + case 3: + case 6: + base_reg = IREG_EBP; + break; + case 4: + base_reg = IREG_ESI; + break; + case 5: + base_reg = IREG_EDI; + break; } - else - { - int base_reg, index_reg, offset; + uop_MOV(ir, IREG_eaaddr, base_reg); - switch (cpu_rm & 7) - { - case 0: case 1: case 7: default: - base_reg = IREG_EBX; - break; - case 2: case 3: case 6: - base_reg = IREG_EBP; - break; - case 4: - base_reg = IREG_ESI; - break; - case 5: - base_reg = IREG_EDI; - break; - } - uop_MOV(ir, IREG_eaaddr, base_reg); + if (!(cpu_rm & 4)) { + if (!(cpu_rm & 1)) + index_reg = IREG_ESI; + else + index_reg = IREG_EDI; - if (!(cpu_rm & 4)) - { - if (!(cpu_rm & 1)) - index_reg = IREG_ESI; - else - index_reg = IREG_EDI; - - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); - } - - switch (cpu_mod) - { - case 1: - offset = (int)(int8_t)((fetchdat >> 8) & 0xff); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); - (*op_pc)++; - break; - case 2: - offset = (fetchdat >> 8) & 0xffff; - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); - (*op_pc) += 2; - break; - } - - uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); - - if (mod1seg[cpu_rm] == &ss && !op_ssegs) - { - op_ea_seg = &cpu_state.seg_ss; - } + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, index_reg); } - codegen_mark_code_present(ir->block, cs+old_pc, ((*op_pc)+1)-old_pc); - return op_ea_seg; -} - -static x86seg *codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) -{ - codeblock_t *block = ir->block; - uint32_t old_pc = (*op_pc) + 1; - uint32_t new_eaaddr; - int extra_bytes = 0; - - if (cpu_rm == 4) - { - uint8_t sib = fetchdat >> 8; + switch (cpu_mod) { + case 1: + offset = (int) (int8_t) ((fetchdat >> 8) & 0xff); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); (*op_pc)++; + break; + case 2: + offset = (fetchdat >> 8) & 0xffff; + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, offset); + (*op_pc) += 2; + break; + } - switch (cpu_mod) - { - case 0: - if ((sib & 7) == 5) - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - extra_bytes = 1; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 5; - } - (*op_pc) += 4; - } - else - { - uop_MOV(ir, IREG_eaaddr, sib & 7); - extra_bytes = 1; - } - break; - case 1: - new_eaaddr = (uint32_t)(int8_t)((fetchdat >> 16) & 0xff); + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + + if (mod1seg[cpu_rm] == &ss && !op_ssegs) { + op_ea_seg = &cpu_state.seg_ss; + } + } + + codegen_mark_code_present(ir->block, cs + old_pc, ((*op_pc) + 1) - old_pc); + return op_ea_seg; +} + +static x86seg * +codegen_generate_ea_32_long(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +{ + codeblock_t *block = ir->block; + uint32_t old_pc = (*op_pc) + 1; + uint32_t new_eaaddr; + int extra_bytes = 0; + + if (cpu_rm == 4) { + uint8_t sib = fetchdat >> 8; + (*op_pc)++; + + switch (cpu_mod) { + case 0: + if ((sib & 7) == 5) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); - (*op_pc)++; - extra_bytes = 2; - break; - case 2: - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - extra_bytes = 1; - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 5; - } - (*op_pc) += 4; - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); - break; + extra_bytes = 5; + } + (*op_pc) += 4; + } else { + uop_MOV(ir, IREG_eaaddr, sib & 7); + extra_bytes = 1; } - if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); -// addbyte(0x05); -// addlong(stack_offset); - } - if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (((sib >> 3) & 7) != 4) - { - switch (sib >> 6) - { - case 0: - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); - break; - case 1: - uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); - break; - case 2: - uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); - break; - case 3: - uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); - break; - } + break; + case 1: + new_eaaddr = (uint32_t) (int8_t) ((fetchdat >> 16) & 0xff); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + (*op_pc)++; + extra_bytes = 2; + break; + case 2: + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + extra_bytes = 1; + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 5; } + (*op_pc) += 4; + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, sib & 7); + break; } - else + if (stack_offset && (sib & 7) == 4 && (cpu_mod || (sib & 7) != 5)) /*ESP*/ { - if (!cpu_mod && cpu_rm == 5) - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); - extra_bytes = 4; - } - - (*op_pc) += 4; - } - else - { - uop_MOV(ir, IREG_eaaddr, cpu_rm); - if (cpu_mod) - { - if (cpu_rm == 5 && !op_ssegs) - op_ea_seg = &cpu_state.seg_ss; - if (cpu_mod == 1) - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t)(int8_t)(fetchdat >> 8)); - (*op_pc)++; - extra_bytes = 1; - } - else - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); - } - else - { - new_eaaddr = fastreadl(cs + (*op_pc) + 1); - uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); - extra_bytes = 4; - } - (*op_pc) += 4; - } - } - } + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, stack_offset); + // addbyte(0x05); + // addlong(stack_offset); } + if (((sib & 7) == 4 || (cpu_mod && (sib & 7) == 5)) && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (((sib >> 3) & 7) != 4) { + switch (sib >> 6) { + case 0: + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7); + break; + case 1: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 1); + break; + case 2: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 2); + break; + case 3: + uop_ADD_LSHIFT(ir, IREG_eaaddr, IREG_eaaddr, (sib >> 3) & 7, 3); + break; + } + } + } else { + if (!cpu_mod && cpu_rm == 5) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + (*op_pc) + 1); + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_MOV_IMM(ir, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } - if (extra_bytes) - codegen_mark_code_present(ir->block, cs+old_pc, extra_bytes); + (*op_pc) += 4; + } else { + uop_MOV(ir, IREG_eaaddr, cpu_rm); + if (cpu_mod) { + if (cpu_rm == 5 && !op_ssegs) + op_ea_seg = &cpu_state.seg_ss; + if (cpu_mod == 1) { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, (uint32_t) (int8_t) (fetchdat >> 8)); + (*op_pc)++; + extra_bytes = 1; + } else { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + (*op_pc) + 1); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_temp0); + } else { + new_eaaddr = fastreadl(cs + (*op_pc) + 1); + uop_ADD_IMM(ir, IREG_eaaddr, IREG_eaaddr, new_eaaddr); + extra_bytes = 4; + } + (*op_pc) += 4; + } + } + } + } - return op_ea_seg; + if (extra_bytes) + codegen_mark_code_present(ir->block, cs + old_pc, extra_bytes); + + return op_ea_seg; } -x86seg *codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset) +x86seg * +codegen_generate_ea(ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset) { - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; - if ((fetchdat & 0xc0) == 0xc0) - return NULL; - if (op_32 & 0x200) - return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); + if ((fetchdat & 0xc0) == 0xc0) + return NULL; + if (op_32 & 0x200) + return codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc, stack_offset); - return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); + return codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, op_pc); } -static uint8_t opcode_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ +static uint8_t opcode_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*10*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*20*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*30*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, /*60*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*70*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ + 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*d0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ + 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, /*f0*/ }; -static uint8_t opcode_0f_modrm[256] = -{ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ - 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ +static uint8_t opcode_0f_modrm[256] = { + 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, /*00*/ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*30*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ - 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, /*60*/ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, /*70*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ - 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ - 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ - 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ - 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ + 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*d0*/ + 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, /*e0*/ + 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0 /*f0*/ }; -void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) +void +codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) { - codeblock_t *block = &codeblock[block_current]; - ir_data_t *ir = codegen_get_ir_data(); - uint32_t op_pc = new_pc; - OpFn *op_table = (OpFn *) x86_dynarec_opcodes; - RecompOpFn *recomp_op_table = recomp_opcodes; - int opcode_shift = 0; - int opcode_mask = 0x3ff; - uint32_t recomp_opcode_mask = 0x1ff; - uint32_t op_32 = use32; - int over = 0; - int test_modrm = 1; - int pc_off = 0; - uint32_t next_pc = 0; + codeblock_t *block = &codeblock[block_current]; + ir_data_t *ir = codegen_get_ir_data(); + uint32_t op_pc = new_pc; + OpFn *op_table = (OpFn *) x86_dynarec_opcodes; + RecompOpFn *recomp_op_table = recomp_opcodes; + int opcode_shift = 0; + int opcode_mask = 0x3ff; + uint32_t recomp_opcode_mask = 0x1ff; + uint32_t op_32 = use32; + int over = 0; + int test_modrm = 1; + int pc_off = 0; + uint32_t next_pc = 0; #ifdef DEBUG_EXTRA - uint8_t last_prefix = 0; + uint8_t last_prefix = 0; #endif - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 0; + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 0; - codegen_timing_start(); + codegen_timing_start(); - while (!over) - { - switch (opcode) - { - case 0x0f: + while (!over) { + switch (opcode) { + case 0x0f: #ifdef DEBUG_EXTRA - last_prefix = 0x0f; + last_prefix = 0x0f; #endif - op_table = (OpFn *) x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; - over = 1; - break; + op_table = (OpFn *) x86_dynarec_opcodes_0f; + recomp_op_table = recomp_opcodes_0f; + over = 1; + break; - case 0x26: /*ES:*/ - op_ea_seg = &cpu_state.seg_es; - op_ssegs = 1; - break; - case 0x2e: /*CS:*/ - op_ea_seg = &cpu_state.seg_cs; - op_ssegs = 1; - break; - case 0x36: /*SS:*/ - op_ea_seg = &cpu_state.seg_ss; - op_ssegs = 1; - break; - case 0x3e: /*DS:*/ - op_ea_seg = &cpu_state.seg_ds; - op_ssegs = 1; - break; - case 0x64: /*FS:*/ - op_ea_seg = &cpu_state.seg_fs; - op_ssegs = 1; - break; - case 0x65: /*GS:*/ - op_ea_seg = &cpu_state.seg_gs; - op_ssegs = 1; - break; + case 0x26: /*ES:*/ + op_ea_seg = &cpu_state.seg_es; + op_ssegs = 1; + break; + case 0x2e: /*CS:*/ + op_ea_seg = &cpu_state.seg_cs; + op_ssegs = 1; + break; + case 0x36: /*SS:*/ + op_ea_seg = &cpu_state.seg_ss; + op_ssegs = 1; + break; + case 0x3e: /*DS:*/ + op_ea_seg = &cpu_state.seg_ds; + op_ssegs = 1; + break; + case 0x64: /*FS:*/ + op_ea_seg = &cpu_state.seg_fs; + op_ssegs = 1; + break; + case 0x65: /*GS:*/ + op_ea_seg = &cpu_state.seg_gs; + op_ssegs = 1; + break; - case 0x66: /*Data size select*/ - op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); - break; - case 0x67: /*Address size select*/ - op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); - break; + case 0x66: /*Data size select*/ + op_32 = ((use32 & 0x100) ^ 0x100) | (op_32 & 0x200); + break; + case 0x67: /*Address size select*/ + op_32 = ((use32 & 0x200) ^ 0x200) | (op_32 & 0x100); + break; - case 0xd8: + case 0xd8: #ifdef DEBUG_EXTRA - last_prefix = 0xd8; + last_prefix = 0xd8; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d8_a32 : (OpFn *) x86_dynarec_opcodes_d8_a16; - recomp_op_table = recomp_opcodes_d8; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xd9: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d8_a32 : (OpFn *) x86_dynarec_opcodes_d8_a16; + recomp_op_table = recomp_opcodes_d8; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xd9: #ifdef DEBUG_EXTRA - last_prefix = 0xd9; + last_prefix = 0xd9; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d9_a32 : (OpFn *) x86_dynarec_opcodes_d9_a16; - recomp_op_table = recomp_opcodes_d9; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xda: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_d9_a32 : (OpFn *) x86_dynarec_opcodes_d9_a16; + recomp_op_table = recomp_opcodes_d9; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xda: #ifdef DEBUG_EXTRA - last_prefix = 0xda; + last_prefix = 0xda; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_da_a32 : (OpFn *) x86_dynarec_opcodes_da_a16; - recomp_op_table = recomp_opcodes_da; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdb: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_da_a32 : (OpFn *) x86_dynarec_opcodes_da_a16; + recomp_op_table = recomp_opcodes_da; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdb: #ifdef DEBUG_EXTRA - last_prefix = 0xdb; + last_prefix = 0xdb; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_db_a32 : (OpFn *) x86_dynarec_opcodes_db_a16; - recomp_op_table = recomp_opcodes_db; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdc: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_db_a32 : (OpFn *) x86_dynarec_opcodes_db_a16; + recomp_op_table = recomp_opcodes_db; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdc: #ifdef DEBUG_EXTRA - last_prefix = 0xdc; + last_prefix = 0xdc; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dc_a32 : (OpFn *) x86_dynarec_opcodes_dc_a16; - recomp_op_table = recomp_opcodes_dc; - opcode_shift = 3; - opcode_mask = 0x1f; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdd: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dc_a32 : (OpFn *) x86_dynarec_opcodes_dc_a16; + recomp_op_table = recomp_opcodes_dc; + opcode_shift = 3; + opcode_mask = 0x1f; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdd: #ifdef DEBUG_EXTRA - last_prefix = 0xdd; + last_prefix = 0xdd; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dd_a32 : (OpFn *) x86_dynarec_opcodes_dd_a16; - recomp_op_table = recomp_opcodes_dd; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xde: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_dd_a32 : (OpFn *) x86_dynarec_opcodes_dd_a16; + recomp_op_table = recomp_opcodes_dd; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xde: #ifdef DEBUG_EXTRA - last_prefix = 0xde; + last_prefix = 0xde; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_de_a32 : (OpFn *) x86_dynarec_opcodes_de_a16; - recomp_op_table = recomp_opcodes_de; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; - case 0xdf: + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_de_a32 : (OpFn *) x86_dynarec_opcodes_de_a16; + recomp_op_table = recomp_opcodes_de; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; + case 0xdf: #ifdef DEBUG_EXTRA - last_prefix = 0xdf; + last_prefix = 0xdf; #endif - op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_df_a32 : (OpFn *) x86_dynarec_opcodes_df_a16; - recomp_op_table = recomp_opcodes_df; - opcode_mask = 0xff; - over = 1; - pc_off = -1; - test_modrm = 0; - block->flags |= CODEBLOCK_HAS_FPU; - break; + op_table = (op_32 & 0x200) ? (OpFn *) x86_dynarec_opcodes_df_a32 : (OpFn *) x86_dynarec_opcodes_df_a16; + recomp_op_table = recomp_opcodes_df; + opcode_mask = 0xff; + over = 1; + pc_off = -1; + test_modrm = 0; + block->flags |= CODEBLOCK_HAS_FPU; + break; - case 0xf0: /*LOCK*/ - break; + case 0xf0: /*LOCK*/ + break; - case 0xf2: /*REPNE*/ + case 0xf2: /*REPNE*/ #ifdef DEBUG_EXTRA - last_prefix = 0xf2; + last_prefix = 0xf2; #endif - op_table = (OpFn *) x86_dynarec_opcodes_REPNE; - recomp_op_table = NULL;//recomp_opcodes_REPNE; - break; - case 0xf3: /*REPE*/ + op_table = (OpFn *) x86_dynarec_opcodes_REPNE; + recomp_op_table = NULL; // recomp_opcodes_REPNE; + break; + case 0xf3: /*REPE*/ #ifdef DEBUG_EXTRA - last_prefix = 0xf3; + last_prefix = 0xf3; #endif - op_table = (OpFn *) x86_dynarec_opcodes_REPE; - recomp_op_table = NULL;//recomp_opcodes_REPE; - break; + op_table = (OpFn *) x86_dynarec_opcodes_REPE; + recomp_op_table = NULL; // recomp_opcodes_REPE; + break; - default: - goto generate_call; - } - fetchdat = fastreadl(cs + op_pc); - codegen_timing_prefix(opcode, fetchdat); - if (cpu_state.abrt) - return; - opcode = fetchdat & 0xff; - if (!pc_off) - fetchdat >>= 8; - - op_pc++; + default: + goto generate_call; } + fetchdat = fastreadl(cs + op_pc); + codegen_timing_prefix(opcode, fetchdat); + if (cpu_state.abrt) + return; + opcode = fetchdat & 0xff; + if (!pc_off) + fetchdat >>= 8; + + op_pc++; + } generate_call: - codegen_instructions[block->ins].pc = cpu_state.oldpc; - codegen_instructions[block->ins].op_ssegs = last_op_ssegs; - codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; - codegen_instructions[block->ins].op_32 = last_op_32; - codegen_instructions[block->ins].TOP = cpu_state.TOP; - codegen_instructions[block->ins].first_uop = ir->wr_pos; + codegen_instructions[block->ins].pc = cpu_state.oldpc; + codegen_instructions[block->ins].op_ssegs = last_op_ssegs; + codegen_instructions[block->ins].op_ea_seg = last_op_ea_seg; + codegen_instructions[block->ins].op_32 = last_op_32; + codegen_instructions[block->ins].TOP = cpu_state.TOP; + codegen_instructions[block->ins].first_uop = ir->wr_pos; - codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); + codegen_timing_opcode(opcode, fetchdat, op_32, op_pc); - codegen_accumulate(ir, ACCREG_cycles, -codegen_block_cycles); - codegen_block_cycles = 0; + codegen_accumulate(ir, ACCREG_cycles, -codegen_block_cycles); + codegen_block_cycles = 0; - if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || - (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) - { - /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with - subsequent instructions, so no cycles may have been deducted for it yet. - To prevent having zero cycle blocks (eg with a jump instruction pointing - to itself), apply the cycles that would be taken if this jump is taken, - then reverse it for subsequent instructions if the jump is not taken*/ - int jump_cycles = 0; + if ((op_table == x86_dynarec_opcodes && ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { + /*On some CPUs (eg K6), a jump/branch instruction may be able to pair with + subsequent instructions, so no cycles may have been deducted for it yet. + To prevent having zero cycle blocks (eg with a jump instruction pointing + to itself), apply the cycles that would be taken if this jump is taken, + then reverse it for subsequent instructions if the jump is not taken*/ + int jump_cycles = 0; - if (codegen_timing_jump_cycles) - codegen_timing_jump_cycles(); + if (codegen_timing_jump_cycles) + codegen_timing_jump_cycles(); - if (jump_cycles) - codegen_accumulate(ir, ACCREG_cycles, -jump_cycles); - codegen_accumulate_flush(ir); - if (jump_cycles) - codegen_accumulate(ir, ACCREG_cycles, jump_cycles); + if (jump_cycles) + codegen_accumulate(ir, ACCREG_cycles, -jump_cycles); + codegen_accumulate_flush(ir); + if (jump_cycles) + codegen_accumulate(ir, ACCREG_cycles, jump_cycles); + } + + if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) { + /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ + uint8_t modrm = fetchdat & 0xff; + uint8_t sib = (fetchdat >> 8) & 0xff; + uint32_t opcode_pc = op_pc + 1; + uint8_t opcode_3dnow; + + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 7) == 4) { + /* Has SIB*/ + opcode_pc++; + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((sib & 0x07) == 0x05) + opcode_pc += 4; + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 4; + else if ((modrm & 0xc7) == 0x05) + opcode_pc += 4; + } + } else { + if ((modrm & 0xc0) == 0x40) + opcode_pc++; + else if ((modrm & 0xc0) == 0x80) + opcode_pc += 2; + else if ((modrm & 0xc7) == 0x06) + opcode_pc += 2; + } } - if (op_table == x86_dynarec_opcodes_0f && opcode == 0x0f) - { - /*3DNow opcodes are stored after ModR/M, SIB and any offset*/ - uint8_t modrm = fetchdat & 0xff; - uint8_t sib = (fetchdat >> 8) & 0xff; - uint32_t opcode_pc = op_pc + 1; - uint8_t opcode_3dnow; + opcode_3dnow = fastreadb(cs + opcode_pc); + if (recomp_opcodes_3DNOW[opcode_3dnow]) { + next_pc = opcode_pc + 1; - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 7) == 4) - { - /* Has SIB*/ - opcode_pc++; - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((sib & 0x07) == 0x05) - opcode_pc += 4; - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 4; - else if ((modrm & 0xc7) == 0x05) - opcode_pc += 4; - } - } - else - { - if ((modrm & 0xc0) == 0x40) - opcode_pc++; - else if ((modrm & 0xc0) == 0x80) - opcode_pc += 2; - else if ((modrm & 0xc7) == 0x06) - opcode_pc += 2; - } - } - - opcode_3dnow = fastreadb(cs + opcode_pc); - if (recomp_opcodes_3DNOW[opcode_3dnow]) - { - next_pc = opcode_pc + 1; - - op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; - recomp_op_table = recomp_opcodes_3DNOW; - opcode = opcode_3dnow; - recomp_opcode_mask = 0xff; - opcode_mask = 0xff; - } + op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; + recomp_op_table = recomp_opcodes_3DNOW; + opcode = opcode_3dnow; + recomp_opcode_mask = 0xff; + opcode_mask = 0xff; } - codegen_mark_code_present(block, cs+old_pc, (op_pc - old_pc) - pc_off); - /* It is apparently a prefixed instruction. */ - // if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) - // goto codegen_skip; + } + codegen_mark_code_present(block, cs + old_pc, (op_pc - old_pc) - pc_off); + /* It is apparently a prefixed instruction. */ + // if ((recomp_op_table == recomp_opcodes) && (opcode == 0x48)) + // goto codegen_skip; - if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) - { - uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); - if (new_pc) - { - if (new_pc != -1) - uop_MOV_IMM(ir, IREG_pc, new_pc); + if (recomp_op_table && recomp_op_table[(opcode | op_32) & recomp_opcode_mask]) { + uint32_t new_pc = recomp_op_table[(opcode | op_32) & recomp_opcode_mask](block, ir, opcode, fetchdat, op_32, op_pc); + if (new_pc) { + if (new_pc != -1) + uop_MOV_IMM(ir, IREG_pc, new_pc); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; - block->ins++; + block->ins++; - if (block->ins >= MAX_INSTRUCTION_COUNT) - CPU_BLOCK_END(); + if (block->ins >= MAX_INSTRUCTION_COUNT) + CPU_BLOCK_END(); - return; - } + return; } + } -// codegen_skip: - if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) - { - op_table = (OpFn *) x86_dynarec_opcodes; - recomp_op_table = recomp_opcodes; + // codegen_skip: + if ((op_table == x86_dynarec_opcodes_REPNE || op_table == x86_dynarec_opcodes_REPE) && !op_table[opcode | op_32]) { + op_table = (OpFn *) x86_dynarec_opcodes; + recomp_op_table = recomp_opcodes; + } + + op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; + + if (!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || (op_table == x86_dynarec_opcodes_3DNOW)) { + int stack_offset = 0; + + if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ + stack_offset = (op_32 & 0x100) ? 4 : 2; + + cpu_mod = (fetchdat >> 6) & 3; + cpu_reg = (fetchdat >> 3) & 7; + cpu_rm = fetchdat & 7; + + uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); + + op_pc += pc_off; + if (cpu_mod != 3 && !(op_32 & 0x200)) { + op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); } - - op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; - - if (!test_modrm || - (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]) || - (op_table == x86_dynarec_opcodes_3DNOW)) - { - int stack_offset = 0; - - if (op_table == x86_dynarec_opcodes && opcode == 0x8f) /*POP*/ - stack_offset = (op_32 & 0x100) ? 4 : 2; - - cpu_mod = (fetchdat >> 6) & 3; - cpu_reg = (fetchdat >> 3) & 7; - cpu_rm = fetchdat & 7; - - uop_MOV_IMM(ir, IREG_rm_mod_reg, cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); - - op_pc += pc_off; - if (cpu_mod != 3 && !(op_32 & 0x200)) - { - op_ea_seg = codegen_generate_ea_16_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc); - } - if (cpu_mod != 3 && (op_32 & 0x200)) - { - op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); - } - op_pc -= pc_off; + if (cpu_mod != 3 && (op_32 & 0x200)) { + op_ea_seg = codegen_generate_ea_32_long(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); } + op_pc -= pc_off; + } #ifdef DEBUG_EXTRA - uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); + uop_LOG_INSTR(ir, opcode | (last_prefix << 8)); #endif - codegen_accumulate_flush(ir); - if (op_table == x86_dynarec_opcodes_3DNOW) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, op_pc+pc_off); - uop_MOV_IMM(ir, IREG_oldpc, old_pc); - if (op_32 != last_op_32) - uop_MOV_IMM(ir, IREG_op32, op_32); - if (op_ea_seg != last_op_ea_seg) - uop_MOV_PTR(ir, IREG_ea_seg, (void *)op_ea_seg); - if (op_ssegs != last_op_ssegs) - uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); - uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); - uop_CALL_INSTRUCTION_FUNC(ir, op); - codegen_mark_code_present(block, cs+cpu_state.pc, 8); + codegen_accumulate_flush(ir); + if (op_table == x86_dynarec_opcodes_3DNOW) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, op_pc + pc_off); + uop_MOV_IMM(ir, IREG_oldpc, old_pc); + if (op_32 != last_op_32) + uop_MOV_IMM(ir, IREG_op32, op_32); + if (op_ea_seg != last_op_ea_seg) + uop_MOV_PTR(ir, IREG_ea_seg, (void *) op_ea_seg); + if (op_ssegs != last_op_ssegs) + uop_MOV_IMM(ir, IREG_ssegs, op_ssegs); + uop_LOAD_FUNC_ARG_IMM(ir, 0, fetchdat); + uop_CALL_INSTRUCTION_FUNC(ir, op); + codegen_mark_code_present(block, cs + cpu_state.pc, 8); - last_op_32 = op_32; - last_op_ea_seg = op_ea_seg; - last_op_ssegs = op_ssegs; - //codegen_block_ins++; + last_op_32 = op_32; + last_op_ea_seg = op_ea_seg; + last_op_ssegs = op_ssegs; + // codegen_block_ins++; - block->ins++; + block->ins++; - if (block->ins >= MAX_INSTRUCTION_COUNT) - CPU_BLOCK_END(); + if (block->ins >= MAX_INSTRUCTION_COUNT) + CPU_BLOCK_END(); - codegen_endpc = (cs + cpu_state.pc) + 8; + codegen_endpc = (cs + cpu_state.pc) + 8; -// if (has_ea) -// fatal("Has EA\n"); + // if (has_ea) + // fatal("Has EA\n"); } diff --git a/src/codegen_new/codegen.h b/src/codegen_new/codegen.h index c6fbac2a9..cc7e3f083 100644 --- a/src/codegen_new/codegen.h +++ b/src/codegen_new/codegen.h @@ -30,34 +30,33 @@ same page). */ -typedef struct codeblock_t -{ - uint32_t pc; - uint32_t _cs; - uint32_t phys, phys_2; - uint16_t status; - uint16_t flags; - uint8_t ins; - uint8_t TOP; +typedef struct codeblock_t { + uint32_t pc; + uint32_t _cs; + uint32_t phys, phys_2; + uint16_t status; + uint16_t flags; + uint8_t ins; + uint8_t TOP; - /*Pointers for codeblock tree, used to search for blocks when hash lookup - fails.*/ - uint16_t parent, left, right; + /*Pointers for codeblock tree, used to search for blocks when hash lookup + fails.*/ + uint16_t parent, left, right; - uint8_t *data; + uint8_t *data; - uint64_t page_mask, page_mask2; - uint64_t *dirty_mask, *dirty_mask2; + uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; - /*Previous and next pointers, for the codeblock list associated with - each physical page. Two sets of pointers, as a codeblock can be - present in two pages.*/ - uint16_t prev, next; - uint16_t prev_2, next_2; + /*Previous and next pointers, for the codeblock list associated with + each physical page. Two sets of pointers, as a codeblock can be + present in two pages.*/ + uint16_t prev, next; + uint16_t prev_2, next_2; - /*First mem_block_t used by this block. Any subsequent mem_block_ts - will be in the list starting at head_mem_block->next.*/ - struct mem_block_t *head_mem_block; + /*First mem_block_t used by this block. Any subsequent mem_block_ts + will be in the list starting at head_mem_block->next.*/ + struct mem_block_t *head_mem_block; } codeblock_t; extern codeblock_t *codeblock; @@ -83,235 +82,206 @@ extern uint8_t *block_write_data; /*Code block is not inlining immediate parameters, parameters must be fetched from memory*/ #define CODEBLOCK_NO_IMMEDIATES 0x80 -#define BLOCK_PC_INVALID 0xffffffff +#define BLOCK_PC_INVALID 0xffffffff -#define BLOCK_INVALID 0 +#define BLOCK_INVALID 0 -static inline int get_block_nr(codeblock_t *block) +static inline int +get_block_nr(codeblock_t *block) { - return ((uintptr_t)block - (uintptr_t)codeblock) / sizeof(codeblock_t); + return ((uintptr_t) block - (uintptr_t) codeblock) / sizeof(codeblock_t); } -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) +static inline codeblock_t * +codeblock_tree_find(uint32_t phys, uint32_t _cs) { - codeblock_t *block; - uint64_t a = _cs | ((uint64_t)phys << 32); + codeblock_t *block; + uint64_t a = _cs | ((uint64_t) phys << 32); - if (!pages[phys >> 12].head) - return NULL; + if (!pages[phys >> 12].head) + return NULL; - block = &codeblock[pages[phys >> 12].head]; - while (block) - { - uint64_t block_cmp = block->_cs | ((uint64_t)block->phys << 32); - if (a == block_cmp) - { - if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) - break; - } - if (a < block_cmp) - block = block->left ? &codeblock[block->left] : NULL; - else - block = block->right ? &codeblock[block->right] : NULL; - } - - return block; -} - -static inline void codeblock_tree_add(codeblock_t *new_block) -{ - codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; - uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); - - if (!pages[new_block->phys >> 12].head) - { - pages[new_block->phys >> 12].head = get_block_nr(new_block); - new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; + block = &codeblock[pages[phys >> 12].head]; + while (block) { + uint64_t block_cmp = block->_cs | ((uint64_t) block->phys << 32); + if (a == block_cmp) { + if (!((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK))) + break; } + if (a < block_cmp) + block = block->left ? &codeblock[block->left] : NULL; else - { - codeblock_t *old_block = NULL; - uint64_t old_block_cmp = 0; + block = block->right ? &codeblock[block->right] : NULL; + } - while (block) - { - old_block = block; - old_block_cmp = old_block->_cs | ((uint64_t)old_block->phys << 32); - - if (a < old_block_cmp) - block = block->left ? &codeblock[block->left] : NULL; - else - block = block->right ? &codeblock[block->right] : NULL; - } - - if (a < old_block_cmp) - old_block->left = get_block_nr(new_block); - else - old_block->right = get_block_nr(new_block); - - new_block->parent = get_block_nr(old_block); - new_block->left = new_block->right = BLOCK_INVALID; - } + return block; } -static inline void codeblock_tree_delete(codeblock_t *block) +static inline void +codeblock_tree_add(codeblock_t *new_block) { - uint16_t parent_nr = block->parent; - codeblock_t *parent; + codeblock_t *block = &codeblock[pages[new_block->phys >> 12].head]; + uint64_t a = new_block->_cs | ((uint64_t) new_block->phys << 32); - if (block->parent) - parent = &codeblock[block->parent]; + if (!pages[new_block->phys >> 12].head) { + pages[new_block->phys >> 12].head = get_block_nr(new_block); + new_block->parent = new_block->left = new_block->right = BLOCK_INVALID; + } else { + codeblock_t *old_block = NULL; + uint64_t old_block_cmp = 0; + + while (block) { + old_block = block; + old_block_cmp = old_block->_cs | ((uint64_t) old_block->phys << 32); + + if (a < old_block_cmp) + block = block->left ? &codeblock[block->left] : NULL; + else + block = block->right ? &codeblock[block->right] : NULL; + } + + if (a < old_block_cmp) + old_block->left = get_block_nr(new_block); else - parent = NULL; + old_block->right = get_block_nr(new_block); - if (!block->left && !block->right) - { - /*Easy case - remove from parent*/ - if (!parent) - pages[block->phys >> 12].head = BLOCK_INVALID; - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - parent->left = BLOCK_INVALID; - if (parent->right == block_nr) - parent->right = BLOCK_INVALID; - } - return; - } - else if (!block->left) - { - /*Only right node*/ - if (!parent_nr) - { - pages[block->phys >> 12].head = block->right; - codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; - } - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - { - parent->left = block->right; - codeblock[parent->left].parent = parent_nr; - } - if (parent->right == block_nr) - { - parent->right = block->right; - codeblock[parent->right].parent = parent_nr; - } - } - return; - } - else if (!block->right) - { - /*Only left node*/ - if (!parent_nr) - { - pages[block->phys >> 12].head = block->left; - codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; - } - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - { - parent->left = block->left; - codeblock[parent->left].parent = parent_nr; - } - if (parent->right == block_nr) - { - parent->right = block->left; - codeblock[parent->right].parent = parent_nr; - } - } - return; - } - else - { - /*Difficult case - node has two children. Walk right child to find lowest node*/ - codeblock_t *lowest = &codeblock[block->right], *highest; - codeblock_t *old_parent; - uint16_t lowest_nr; - - while (lowest->left) - lowest = &codeblock[lowest->left]; - lowest_nr = get_block_nr(lowest); - - old_parent = &codeblock[lowest->parent]; - - /*Replace deleted node with lowest node*/ - if (!parent_nr) - pages[block->phys >> 12].head = lowest_nr; - else - { - uint16_t block_nr = get_block_nr(block); - - if (parent->left == block_nr) - parent->left = lowest_nr; - if (parent->right == block_nr) - parent->right = lowest_nr; - } - - lowest->parent = parent_nr; - lowest->left = block->left; - if (lowest->left) - codeblock[lowest->left].parent = lowest_nr; - - old_parent->left = BLOCK_INVALID; - - highest = &codeblock[lowest->right]; - if (!lowest->right) - { - if (lowest_nr != block->right) - { - lowest->right = block->right; - codeblock[block->right].parent = lowest_nr; - } - return; - } - - while (highest->right) - highest = &codeblock[highest->right]; - - if (block->right && block->right != lowest_nr) - { - highest->right = block->right; - codeblock[block->right].parent = get_block_nr(highest); - } - } + new_block->parent = get_block_nr(old_block); + new_block->left = new_block->right = BLOCK_INVALID; + } } -#define PAGE_MASK_MASK 63 +static inline void +codeblock_tree_delete(codeblock_t *block) +{ + uint16_t parent_nr = block->parent; + codeblock_t *parent; + + if (block->parent) + parent = &codeblock[block->parent]; + else + parent = NULL; + + if (!block->left && !block->right) { + /*Easy case - remove from parent*/ + if (!parent) + pages[block->phys >> 12].head = BLOCK_INVALID; + else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = BLOCK_INVALID; + if (parent->right == block_nr) + parent->right = BLOCK_INVALID; + } + return; + } else if (!block->left) { + /*Only right node*/ + if (!parent_nr) { + pages[block->phys >> 12].head = block->right; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) { + parent->left = block->right; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) { + parent->right = block->right; + codeblock[parent->right].parent = parent_nr; + } + } + return; + } else if (!block->right) { + /*Only left node*/ + if (!parent_nr) { + pages[block->phys >> 12].head = block->left; + codeblock[pages[block->phys >> 12].head].parent = BLOCK_INVALID; + } else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) { + parent->left = block->left; + codeblock[parent->left].parent = parent_nr; + } + if (parent->right == block_nr) { + parent->right = block->left; + codeblock[parent->right].parent = parent_nr; + } + } + return; + } else { + /*Difficult case - node has two children. Walk right child to find lowest node*/ + codeblock_t *lowest = &codeblock[block->right], *highest; + codeblock_t *old_parent; + uint16_t lowest_nr; + + while (lowest->left) + lowest = &codeblock[lowest->left]; + lowest_nr = get_block_nr(lowest); + + old_parent = &codeblock[lowest->parent]; + + /*Replace deleted node with lowest node*/ + if (!parent_nr) + pages[block->phys >> 12].head = lowest_nr; + else { + uint16_t block_nr = get_block_nr(block); + + if (parent->left == block_nr) + parent->left = lowest_nr; + if (parent->right == block_nr) + parent->right = lowest_nr; + } + + lowest->parent = parent_nr; + lowest->left = block->left; + if (lowest->left) + codeblock[lowest->left].parent = lowest_nr; + + old_parent->left = BLOCK_INVALID; + + highest = &codeblock[lowest->right]; + if (!lowest->right) { + if (lowest_nr != block->right) { + lowest->right = block->right; + codeblock[block->right].parent = lowest_nr; + } + return; + } + + while (highest->right) + highest = &codeblock[highest->right]; + + if (block->right && block->right != lowest_nr) { + highest->right = block->right; + codeblock[block->right].parent = get_block_nr(highest); + } + } +} + +#define PAGE_MASK_MASK 63 #define PAGE_MASK_SHIFT 6 void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len); -static inline void codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) +static inline void +codegen_mark_code_present(codeblock_t *block, uint32_t start_pc, int len) { - if (len == 1) - { - if (block->flags & CODEBLOCK_BYTE_MASK) - { - if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ - block->page_mask |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); - else - block->page_mask2 |= ((uint64_t)1 << (start_pc & PAGE_MASK_MASK)); - } - else - { - if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ - block->page_mask |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); - else - block->page_mask2 |= ((uint64_t)1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); - } + if (len == 1) { + if (block->flags & CODEBLOCK_BYTE_MASK) { + if (!((start_pc ^ block->pc) & ~0x3f)) /*Starts in second page*/ + block->page_mask |= ((uint64_t) 1 << (start_pc & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t) 1 << (start_pc & PAGE_MASK_MASK)); + } else { + if (!((start_pc ^ block->pc) & ~0xfff)) /*Starts in second page*/ + block->page_mask |= ((uint64_t) 1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); + else + block->page_mask2 |= ((uint64_t) 1 << ((start_pc >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK)); } - else - codegen_mark_code_present_multibyte(block, start_pc, len); + } else + codegen_mark_code_present_multibyte(block, start_pc, len); } extern void codegen_init(void); @@ -329,7 +299,7 @@ extern void codegen_set_op32(void); extern void codegen_flush(void); extern void codegen_check_flush(struct page_t *page, uint64_t mask, uint32_t phys_addr); struct ir_data_t; -x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset); +x86seg *codegen_generate_ea(struct ir_data_t *ir, x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32, int stack_offset); extern void codegen_check_seg_read(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); extern void codegen_check_seg_write(codeblock_t *block, struct ir_data_t *ir, x86seg *seg); @@ -338,7 +308,7 @@ extern int codegen_purge_purgable_list(void); will only be called when the allocator is out of memory*/ extern void codegen_delete_random_block(int required_mem_block); -extern int cpu_block_end; +extern int cpu_block_end; extern uint32_t codegen_endpc; extern int cpu_reps; @@ -353,14 +323,13 @@ extern void (*codegen_timing_block_start)(void); extern void (*codegen_timing_block_end)(void); extern int (*codegen_timing_jump_cycles)(void); -typedef struct codegen_timing_t -{ - void (*start)(void); - void (*prefix)(uint8_t prefix, uint32_t fetchdat); - void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); - void (*block_start)(void); - void (*block_end)(void); - int (*jump_cycles)(void); +typedef struct codegen_timing_t { + void (*start)(void); + void (*prefix)(uint8_t prefix, uint32_t fetchdat); + void (*opcode)(uint8_t opcode, uint32_t fetchdat, int op_32, uint32_t op_pc); + void (*block_start)(void); + void (*block_end)(void); + int (*jump_cycles)(void); } codegen_timing_t; extern codegen_timing_t codegen_timing_pentium; @@ -371,7 +340,6 @@ extern codegen_timing_t codegen_timing_winchip2; extern codegen_timing_t codegen_timing_k6; extern codegen_timing_t codegen_timing_p6; - void codegen_timing_set(codegen_timing_t *timing); extern int block_current; @@ -382,8 +350,8 @@ extern int block_pos; /*Current physical page of block being recompiled. -1 if no recompilation taking place */ extern uint32_t recomp_page; -extern x86seg *op_ea_seg; -extern int op_ssegs; +extern x86seg *op_ea_seg; +extern int op_ssegs; extern uint32_t op_old_pc; /*Set to 1 if flags have been changed in the block being recompiled, and hence @@ -400,11 +368,11 @@ extern int codegen_in_recompile; void codegen_generate_reset(void); -int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); +int codegen_get_instruction_uop(codeblock_t *block, uint32_t pc, int *first_instruction, int *TOP); void codegen_set_loop_start(struct ir_data_t *ir, int first_instruction); #ifdef DEBUG_EXTRA -extern uint32_t instr_counts[256*256]; +extern uint32_t instr_counts[256 * 256]; #endif #endif diff --git a/src/codegen_new/codegen_accumulate.c b/src/codegen_new/codegen_accumulate.c index b9ec78577..d9ae38af8 100644 --- a/src/codegen_new/codegen_accumulate.c +++ b/src/codegen_new/codegen_accumulate.c @@ -9,34 +9,36 @@ static struct { - int count; - int dest_reg; -} acc_regs[] = -{ - [ACCREG_cycles] = {0, IREG_cycles} + int count; + int dest_reg; +} acc_regs[] = { + [ACCREG_cycles] = {0, IREG_cycles} }; -void codegen_accumulate(ir_data_t *ir, int acc_reg, int delta) +void +codegen_accumulate(ir_data_t *ir, int acc_reg, int delta) { - acc_regs[acc_reg].count += delta; + acc_regs[acc_reg].count += delta; #ifdef USE_ACYCS - if ((acc_reg == ACCREG_cycles) && (delta != 0)) { - uop_ADD_IMM(ir, IREG_acycs, IREG_acycs, -delta); - } + if ((acc_reg == ACCREG_cycles) && (delta != 0)) { + uop_ADD_IMM(ir, IREG_acycs, IREG_acycs, -delta); + } #endif } -void codegen_accumulate_flush(ir_data_t *ir) +void +codegen_accumulate_flush(ir_data_t *ir) { - if (acc_regs[0].count) { - uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count); - } + if (acc_regs[0].count) { + uop_ADD_IMM(ir, acc_regs[0].dest_reg, acc_regs[0].dest_reg, acc_regs[0].count); + } - acc_regs[0].count = 0; + acc_regs[0].count = 0; } -void codegen_accumulate_reset(void) +void +codegen_accumulate_reset(void) { - acc_regs[0].count = 0; + acc_regs[0].count = 0; } diff --git a/src/codegen_new/codegen_accumulate.h b/src/codegen_new/codegen_accumulate.h index ccbed2afa..5744c6362 100644 --- a/src/codegen_new/codegen_accumulate.h +++ b/src/codegen_new/codegen_accumulate.h @@ -1,8 +1,7 @@ -enum -{ - ACCREG_cycles = 0, +enum { + ACCREG_cycles = 0, - ACCREG_COUNT + ACCREG_COUNT }; struct ir_data_t; diff --git a/src/codegen_new/codegen_allocator.c b/src/codegen_new/codegen_allocator.c index 84f837a97..2badc35e8 100644 --- a/src/codegen_new/codegen_allocator.c +++ b/src/codegen_new/codegen_allocator.c @@ -1,10 +1,10 @@ #if defined(__unix__) || defined(__APPLE__) || defined(__HAIKU__) -#include -#include -#include +# include +# include +# include #endif #if defined WIN32 || defined _WIN32 || defined _WIN32 -#include +# include #endif #include @@ -17,118 +17,116 @@ #include "codegen.h" #include "codegen_allocator.h" -typedef struct mem_block_t -{ - uint32_t offset; /*Offset into mem_block_alloc*/ - uint32_t next; - uint16_t code_block; +typedef struct mem_block_t { + uint32_t offset; /*Offset into mem_block_alloc*/ + uint32_t next; + uint16_t code_block; } mem_block_t; static mem_block_t mem_blocks[MEM_BLOCK_NR]; -static uint32_t mem_block_free_list; -static uint8_t *mem_block_alloc = NULL; +static uint32_t mem_block_free_list; +static uint8_t *mem_block_alloc = NULL; int codegen_allocator_usage = 0; -void codegen_allocator_init(void) +void +codegen_allocator_init(void) { - int c; + int c; #if defined WIN32 || defined _WIN32 || defined _WIN32 - mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); - /* TODO: check deployment target: older Intel-based versions of macOS don't play - nice with MAP_JIT. */ + mem_block_alloc = VirtualAlloc(NULL, MEM_BLOCK_NR * MEM_BLOCK_SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE); + /* TODO: check deployment target: older Intel-based versions of macOS don't play + nice with MAP_JIT. */ #elif defined(__APPLE__) && defined(MAP_JIT) - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_JIT, -1, 0); + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE | MAP_JIT, -1, 0); #else - mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANON|MAP_PRIVATE, -1, 0); + mem_block_alloc = mmap(0, MEM_BLOCK_NR * MEM_BLOCK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0); #endif - for (c = 0; c < MEM_BLOCK_NR; c++) - { - mem_blocks[c].offset = c * MEM_BLOCK_SIZE; - mem_blocks[c].code_block = BLOCK_INVALID; - if (c < MEM_BLOCK_NR-1) - mem_blocks[c].next = c+2; - else - mem_blocks[c].next = 0; - } - mem_block_free_list = 1; -} - -mem_block_t *codegen_allocator_allocate(mem_block_t *parent, int code_block) -{ - mem_block_t *block; - uint32_t block_nr; - - while (!mem_block_free_list) - { - /*Pick a random memory block and free the owning code block*/ - block_nr = rand() & MEM_BLOCK_MASK; - block = &mem_blocks[block_nr]; - - if (block->code_block && block->code_block != code_block) - codegen_delete_block(&codeblock[block->code_block]); - } - - /*Remove from free list*/ - block_nr = mem_block_free_list; - block = &mem_blocks[block_nr-1]; - mem_block_free_list = block->next; - - block->code_block = code_block; - if (parent) - { - /*Add to parent list*/ - block->next = parent->next; - parent->next = block_nr; - } + for (c = 0; c < MEM_BLOCK_NR; c++) { + mem_blocks[c].offset = c * MEM_BLOCK_SIZE; + mem_blocks[c].code_block = BLOCK_INVALID; + if (c < MEM_BLOCK_NR - 1) + mem_blocks[c].next = c + 2; else - block->next = 0; - - codegen_allocator_usage++; - return block; + mem_blocks[c].next = 0; + } + mem_block_free_list = 1; } -void codegen_allocator_free(mem_block_t *block) + +mem_block_t * +codegen_allocator_allocate(mem_block_t *parent, int code_block) { - int block_nr = (((uintptr_t)block - (uintptr_t)mem_blocks) / sizeof(mem_block_t)) + 1; + mem_block_t *block; + uint32_t block_nr; - while (1) - { - int next_block_nr = block->next; - codegen_allocator_usage--; + while (!mem_block_free_list) { + /*Pick a random memory block and free the owning code block*/ + block_nr = rand() & MEM_BLOCK_MASK; + block = &mem_blocks[block_nr]; - block->next = mem_block_free_list; - block->code_block = BLOCK_INVALID; - mem_block_free_list = block_nr; - block_nr = next_block_nr; + if (block->code_block && block->code_block != code_block) + codegen_delete_block(&codeblock[block->code_block]); + } - if (block_nr) - block = &mem_blocks[block_nr - 1]; - else - break; - } + /*Remove from free list*/ + block_nr = mem_block_free_list; + block = &mem_blocks[block_nr - 1]; + mem_block_free_list = block->next; + + block->code_block = code_block; + if (parent) { + /*Add to parent list*/ + block->next = parent->next; + parent->next = block_nr; + } else + block->next = 0; + + codegen_allocator_usage++; + return block; } - -uint8_t *codeblock_allocator_get_ptr(mem_block_t *block) +void +codegen_allocator_free(mem_block_t *block) { - return &mem_block_alloc[block->offset]; + int block_nr = (((uintptr_t) block - (uintptr_t) mem_blocks) / sizeof(mem_block_t)) + 1; + + while (1) { + int next_block_nr = block->next; + codegen_allocator_usage--; + + block->next = mem_block_free_list; + block->code_block = BLOCK_INVALID; + mem_block_free_list = block_nr; + block_nr = next_block_nr; + + if (block_nr) + block = &mem_blocks[block_nr - 1]; + else + break; + } } -void codegen_allocator_clean_blocks(struct mem_block_t *block) +uint8_t * +codeblock_allocator_get_ptr(mem_block_t *block) +{ + return &mem_block_alloc[block->offset]; +} + +void +codegen_allocator_clean_blocks(struct mem_block_t *block) { #if defined __ARM_EABI__ || defined _ARM_ || defined __aarch64__ || defined _M_ARM || defined _M_ARM64 - while (1) - { -#ifndef _MSC_VER - __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); -#else - FlushInstructionCache(GetCurrentProcess(), &mem_block_alloc[block->offset], MEM_BLOCK_SIZE); -#endif - if (block->next) - block = &mem_blocks[block->next - 1]; - else - break; - } + while (1) { +# ifndef _MSC_VER + __clear_cache(&mem_block_alloc[block->offset], &mem_block_alloc[block->offset + MEM_BLOCK_SIZE]); +# else + FlushInstructionCache(GetCurrentProcess(), &mem_block_alloc[block->offset], MEM_BLOCK_SIZE); +# endif + if (block->next) + block = &mem_blocks[block->next - 1]; + else + break; + } #endif } diff --git a/src/codegen_new/codegen_allocator.h b/src/codegen_new/codegen_allocator.h index 1b808f127..21d4dbb0c 100644 --- a/src/codegen_new/codegen_allocator.h +++ b/src/codegen_new/codegen_allocator.h @@ -14,12 +14,12 @@ instruction. ARMv7 is restricted to +/- 32 MB, ARMv8 to +/- 128 MB, x86 to +/- 2GB. As a result, total memory size is limited to 32 MB on ARMv7*/ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#define MEM_BLOCK_NR 32768 +# define MEM_BLOCK_NR 32768 #else -#define MEM_BLOCK_NR 131072 +# define MEM_BLOCK_NR 131072 #endif -#define MEM_BLOCK_MASK (MEM_BLOCK_NR-1) +#define MEM_BLOCK_MASK (MEM_BLOCK_NR - 1) #define MEM_BLOCK_SIZE 0x3c0 void codegen_allocator_init(void); diff --git a/src/codegen_new/codegen_backend.h b/src/codegen_new/codegen_backend.h index c45e0be88..901b5e9d9 100644 --- a/src/codegen_new/codegen_backend.h +++ b/src/codegen_new/codegen_backend.h @@ -2,15 +2,15 @@ #define _CODEGEN_BACKEND_H_ #if defined __amd64__ || defined _M_X64 -#include "codegen_backend_x86-64.h" +# include "codegen_backend_x86-64.h" #elif defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include "codegen_backend_x86.h" +# include "codegen_backend_x86.h" #elif defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include "codegen_backend_arm.h" +# include "codegen_backend_arm.h" #elif defined __aarch64__ || defined _M_ARM64 -#include "codegen_backend_arm64.h" +# include "codegen_backend_arm64.h" #else -#error Dynamic recompiler not implemented on your platform +# error Dynamic recompiler not implemented on your platform #endif void codegen_backend_init(void); @@ -29,10 +29,9 @@ extern const uOpFn uop_handlers[]; /*Register will not be preserved across function calls*/ #define HOST_REG_FLAG_VOLATILE (1 << 0) -typedef struct host_reg_def_t -{ - int reg; - int flags; +typedef struct host_reg_def_t { + int reg; + int flags; } host_reg_def_t; extern host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS]; diff --git a/src/codegen_new/codegen_backend_arm.c b/src/codegen_new/codegen_backend_arm.c index 478a97f0d..a389f239f 100644 --- a/src/codegen_new/codegen_backend_arm.c +++ b/src/codegen_new/codegen_backend_arm.c @@ -1,28 +1,28 @@ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm_defs.h" -#include "codegen_backend_arm_ops.h" -#include "codegen_reg.h" -#include "x86.h" -#include "x87.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm_defs.h" +# include "codegen_backend_arm_ops.h" +# include "codegen_reg.h" +# include "x86.h" +# include "x87.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -43,329 +43,325 @@ void *codegen_fp_round; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - {REG_R4, 0}, - {REG_R5, 0}, - {REG_R6, 0}, - {REG_R7, 0}, - {REG_R8, 0}, - {REG_R9, 0}, - {REG_R11, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + {REG_R4, 0}, + { REG_R5, 0}, + { REG_R6, 0}, + { REG_R7, 0}, + { REG_R8, 0}, + { REG_R9, 0}, + { REG_R11, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_D8, 0}, - {REG_D9, 0}, - {REG_D10, 0}, - {REG_D11, 0}, - {REG_D12, 0}, - {REG_D13, 0}, - {REG_D14, 0}, - {REG_D15, 0} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_D8, 0}, + { REG_D9, 0}, + { REG_D10, 0}, + { REG_D11, 0}, + { REG_D12, 0}, + { REG_D13, 0}, + { REG_D14, 0}, + { REG_D15, 0} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address - Out - R0 = data, R1 = abrt*/ - /*MOV R1, R0, LSR #12 - MOV R2, #readlookup2 - LDR R1, [R2, R1, LSL #2] - CMP R1, #-1 - BNE + - LDRB R0, [R1, R0] - MOV R1, #0 - MOV PC, LR - * STR LR, [SP, -4]! - BL readmembl - LDRB R1, cpu_state.abrt - LDR PC, [SP], #4 - */ - codegen_alloc(block, 80); - host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); - host_arm_MOV_IMM(block, REG_R2, (uint32_t)readlookup2); - host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); - if (size != 1) - { - host_arm_TST_IMM(block, REG_R0, size-1); - misaligned_offset = host_arm_BNE_(block); - } - host_arm_CMP_IMM(block, REG_R1, -1); - branch_offset = host_arm_BEQ_(block); - if (size == 1 && !is_float) - host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 2 && !is_float) - host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4 && !is_float) - host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); - else if (size == 4 && is_float) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); - host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); - } - else if (size == 8) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); - host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); - } - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_MOV_REG(block, REG_PC, REG_LR); + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmembl + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + codegen_alloc(block, 80); + host_arm_MOV_REG_LSR(block, REG_R1, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R2, (uint32_t) readlookup2); + host_arm_LDR_REG_LSL(block, REG_R1, REG_R2, REG_R1, 2); + if (size != 1) { + host_arm_TST_IMM(block, REG_R0, size - 1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R1, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1 && !is_float) + host_arm_LDRB_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 2 && !is_float) + host_arm_LDRH_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && !is_float) + host_arm_LDR_REG(block, REG_R0, REG_R1, REG_R0); + else if (size == 4 && is_float) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_S(block, REG_D_TEMP, REG_R0, 0); + } else if (size == 8) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R1); + host_arm_VLDR_D(block, REG_D_TEMP, REG_R0, 0); + } + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); - if (size == 1) - host_arm_BL(block, (uintptr_t)readmembl); - else if (size == 2) - host_arm_BL(block, (uintptr_t)readmemwl); - else if (size == 4) - host_arm_BL(block, (uintptr_t)readmemll); - else if (size == 8) - host_arm_BL(block, (uintptr_t)readmemql); - else - fatal("build_load_routine - unknown size %i\n", size); - if (size == 4 && is_float) - host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); - else if (size == 8) - host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); + *branch_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 1) + host_arm_BL(block, (uintptr_t) readmembl); + else if (size == 2) + host_arm_BL(block, (uintptr_t) readmemwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t) readmemll); + else if (size == 8) + host_arm_BL(block, (uintptr_t) readmemql); + else + fatal("build_load_routine - unknown size %i\n", size); + if (size == 4 && is_float) + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_R0); + else if (size == 8) + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address - Out - R0 = data, R1 = abrt*/ - /*MOV R1, R0, LSR #12 - MOV R2, #readlookup2 - LDR R1, [R2, R1, LSL #2] - CMP R1, #-1 - BNE + - LDRB R0, [R1, R0] - MOV R1, #0 - MOV PC, LR - * STR LR, [SP, -4]! - BL readmembl - LDRB R1, cpu_state.abrt - LDR PC, [SP], #4 - */ - codegen_alloc(block, 80); - host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); - host_arm_MOV_IMM(block, REG_R3, (uint32_t)writelookup2); - host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); - if (size != 1) - { - host_arm_TST_IMM(block, REG_R0, size-1); - misaligned_offset = host_arm_BNE_(block); - } - host_arm_CMP_IMM(block, REG_R2, -1); - branch_offset = host_arm_BEQ_(block); - if (size == 1 && !is_float) - host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 2 && !is_float) - host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4 && !is_float) - host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); - else if (size == 4 && is_float) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); - host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); - } - else if (size == 8) - { - host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); - host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); - } - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_MOV_REG(block, REG_PC, REG_LR); + /*In - R0 = address + Out - R0 = data, R1 = abrt*/ + /*MOV R1, R0, LSR #12 + MOV R2, #readlookup2 + LDR R1, [R2, R1, LSL #2] + CMP R1, #-1 + BNE + + LDRB R0, [R1, R0] + MOV R1, #0 + MOV PC, LR + * STR LR, [SP, -4]! + BL readmembl + LDRB R1, cpu_state.abrt + LDR PC, [SP], #4 + */ + codegen_alloc(block, 80); + host_arm_MOV_REG_LSR(block, REG_R2, REG_R0, 12); + host_arm_MOV_IMM(block, REG_R3, (uint32_t) writelookup2); + host_arm_LDR_REG_LSL(block, REG_R2, REG_R3, REG_R2, 2); + if (size != 1) { + host_arm_TST_IMM(block, REG_R0, size - 1); + misaligned_offset = host_arm_BNE_(block); + } + host_arm_CMP_IMM(block, REG_R2, -1); + branch_offset = host_arm_BEQ_(block); + if (size == 1 && !is_float) + host_arm_STRB_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 2 && !is_float) + host_arm_STRH_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && !is_float) + host_arm_STR_REG(block, REG_R1, REG_R2, REG_R0); + else if (size == 4 && is_float) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_S(block, REG_D_TEMP, REG_R0, 0); + } else if (size == 8) { + host_arm_ADD_REG(block, REG_R0, REG_R0, REG_R2); + host_arm_VSTR_D(block, REG_D_TEMP, REG_R0, 0); + } + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_MOV_REG(block, REG_PC, REG_LR); - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - if (size != 1) - *misaligned_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 8) & 0x3fffffc) >> 2; - host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); - if (size == 4 && is_float) - host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); - else if (size == 8) - host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); - if (size == 1) - host_arm_BL(block, (uintptr_t)writemembl); - else if (size == 2) - host_arm_BL(block, (uintptr_t)writememwl); - else if (size == 4) - host_arm_BL(block, (uintptr_t)writememll); - else if (size == 8) - host_arm_BL_r1(block, (uintptr_t)writememql); - else - fatal("build_store_routine - unknown size %i\n", size); - host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); - host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); + *branch_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 8) & 0x3fffffc) >> 2; + if (size != 1) + *misaligned_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 8) & 0x3fffffc) >> 2; + host_arm_STR_IMM_WB(block, REG_LR, REG_HOST_SP, -4); + if (size == 4 && is_float) + host_arm_VMOV_32_S(block, REG_R1, REG_D_TEMP); + else if (size == 8) + host_arm_VMOV_64_D(block, REG_R2, REG_R3, REG_D_TEMP); + if (size == 1) + host_arm_BL(block, (uintptr_t) writemembl); + else if (size == 2) + host_arm_BL(block, (uintptr_t) writememwl); + else if (size == 4) + host_arm_BL(block, (uintptr_t) writememll); + else if (size == 8) + host_arm_BL_r1(block, (uintptr_t) writememql); + else + fatal("build_store_routine - unknown size %i\n", size); + host_arm_LDRB_ABS(block, REG_R1, &cpu_state.abrt); + host_arm_LDR_IMM_POST(block, REG_PC, REG_HOST_SP, 4); } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &block_write_data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &block_write_data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &block_write_data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &block_write_data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &block_write_data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &block_write_data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &block_write_data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &block_write_data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &block_write_data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &block_write_data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &block_write_data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &block_write_data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &block_write_data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &block_write_data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &block_write_data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &block_write_data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &block_write_data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &block_write_data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &block_write_data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &block_write_data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &block_write_data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &block_write_data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &block_write_data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &block_write_data[block_pos]; + build_store_routine(block, 8, 1); } /*VFP has a specific round-to-zero instruction, and the default rounding mode is nearest. For round up/down, temporarily change the rounding mode in FPCSR*/ -#define FPCSR_ROUNDING_MASK (3 << 22) -#define FPCSR_ROUNDING_UP (1 << 22) -#define FPCSR_ROUNDING_DOWN (2 << 22) +# define FPCSR_ROUNDING_MASK (3 << 22) +# define FPCSR_ROUNDING_UP (1 << 22) +# define FPCSR_ROUNDING_DOWN (2 << 22) -static void build_fp_round_routine(codeblock_t *block) +static void +build_fp_round_routine(codeblock_t *block) { - uint32_t *jump_table; + uint32_t *jump_table; - codegen_alloc(block, 80); + codegen_alloc(block, 80); - host_arm_MOV_REG(block, REG_TEMP2, REG_LR); - host_arm_MOV_REG(block, REG_LR, REG_TEMP2); - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); - host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); - host_arm_NOP(block); + host_arm_MOV_REG(block, REG_TEMP2, REG_LR); + host_arm_MOV_REG(block, REG_LR, REG_TEMP2); + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.new_fp_control - (uintptr_t) &cpu_state); + host_arm_LDR_REG(block, REG_PC, REG_PC, REG_TEMP); + host_arm_NOP(block); - jump_table = (uint32_t *)&block_write_data[block_pos]; - host_arm_NOP(block); - host_arm_NOP(block); - host_arm_NOP(block); - host_arm_NOP(block); + jump_table = (uint32_t *) &block_write_data[block_pos]; + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); + host_arm_NOP(block); - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_NEAREST] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // tie even + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); - host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); - host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); - host_arm_VMSR_FPSCR(block, REG_TEMP2); - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_VMSR_FPSCR(block, REG_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_UP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // pos inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.old_fp_control - (uintptr_t) &cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP2, FPCSR_ROUNDING_UP); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.old_fp_control - (uintptr_t)&cpu_state); - host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); - host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); - host_arm_VMSR_FPSCR(block, REG_TEMP2); - host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_VMSR_FPSCR(block, REG_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_DOWN] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // neg inf + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.old_fp_control - (uintptr_t) &cpu_state); + host_arm_BIC_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_MASK); + host_arm_ORR_IMM(block, REG_TEMP2, REG_TEMP, FPCSR_ROUNDING_DOWN); + host_arm_VMSR_FPSCR(block, REG_TEMP2); + host_arm_VCVTR_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_VMSR_FPSCR(block, REG_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero - host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); - host_arm_MOV_REG(block, REG_PC, REG_LR); + jump_table[X87_ROUNDING_CHOP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // zero + host_arm_VCVT_IS_D(block, REG_D_TEMP, REG_D_TEMP); + host_arm_MOV_REG(block, REG_PC, REG_LR); } -void codegen_backend_init(void) +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(&codeblock[block_current]); -//pclog("block_pos=%i\n", block_pos); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(&codeblock[block_current]); + // pclog("block_pos=%i\n", block_pos); - codegen_fp_round = &block_write_data[block_pos]; - build_fp_round_routine(&codeblock[block_current]); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(&codeblock[block_current]); - codegen_alloc(block, 80); - codegen_gpf_rout = &block_write_data[block_pos]; - host_arm_MOV_IMM(block, REG_R0, 0); - host_arm_MOV_IMM(block, REG_R1, 0); - host_arm_call(block, x86gpf); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm_MOV_IMM(block, REG_R0, 0); + host_arm_MOV_IMM(block, REG_R1, 0); + host_arm_call(block, x86gpf); - codegen_exit_rout = &block_write_data[block_pos]; - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - block_write_data = NULL; -//fatal("block_pos=%i\n", block_pos); - asm("vmrs %0, fpscr\n" - : "=r" (cpu_state.old_fp_control) - ); - if ((cpu_state.old_fp_control >> 22) & 3) - fatal("VFP not in nearest rounding mode\n"); + block_write_data = NULL; + // fatal("block_pos=%i\n", block_pos); + asm("vmrs %0, fpscr\n" + : "=r"(cpu_state.old_fp_control)); + if ((cpu_state.old_fp_control >> 22) & 3) + fatal("VFP not in nearest rounding mode\n"); } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - if (mode < 0 || mode > 3) - fatal("codegen_set_rounding_mode - invalid mode\n"); - cpu_state.new_fp_control = mode << 2; + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 2; } /*R10 - cpu_state*/ -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; + block_pos = BLOCK_START; - /*Entry code*/ + /*Entry code*/ - host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); - host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t)&cpu_state); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - } + host_arm_STMDB_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_LR); + host_arm_SUB_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_MOV_IMM(block, REG_CPUSTATE, (uint32_t) &cpu_state); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm_STR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + } } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); - host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); + host_arm_ADD_IMM(block, REG_HOST_SP, REG_HOST_SP, 0x40); + host_arm_LDMIA_WB(block, REG_HOST_SP, REG_MASK_LOCAL | REG_MASK_PC); - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen_new/codegen_backend_arm.h b/src/codegen_new/codegen_backend_arm.h index 8b8936a98..a3e236d4e 100644 --- a/src/codegen_new/codegen_backend_arm.h +++ b/src/codegen_new/codegen_backend_arm.h @@ -1,15 +1,15 @@ #include "codegen_backend_arm_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) -#define BLOCK_MAX 0x3c0 +#define BLOCK_MAX 0x3c0 void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask); diff --git a/src/codegen_new/codegen_backend_arm64.c b/src/codegen_new/codegen_backend_arm64.c index 8941285cd..48d949406 100644 --- a/src/codegen_new/codegen_backend_arm64.c +++ b/src/codegen_new/codegen_backend_arm64.c @@ -1,28 +1,28 @@ #if defined __aarch64__ || defined _M_ARM64 -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm64_defs.h" -#include "codegen_backend_arm64_ops.h" -#include "codegen_reg.h" -#include "x86.h" -#include "x87.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm64_defs.h" +# include "codegen_backend_arm64_ops.h" +# include "codegen_reg.h" +# include "x86.h" +# include "x87.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -44,334 +44,335 @@ void *codegen_fp_round_quad; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - {REG_X19, 0}, - {REG_X20, 0}, - {REG_X21, 0}, - {REG_X22, 0}, - {REG_X23, 0}, - {REG_X24, 0}, - {REG_X25, 0}, - {REG_X26, 0}, - {REG_X27, 0}, - {REG_X28, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + {REG_X19, 0}, + { REG_X20, 0}, + { REG_X21, 0}, + { REG_X22, 0}, + { REG_X23, 0}, + { REG_X24, 0}, + { REG_X25, 0}, + { REG_X26, 0}, + { REG_X27, 0}, + { REG_X28, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_V8, 0}, - {REG_V9, 0}, - {REG_V10, 0}, - {REG_V11, 0}, - {REG_V12, 0}, - {REG_V13, 0}, - {REG_V14, 0}, - {REG_V15, 0} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_V8, 0}, + { REG_V9, 0}, + { REG_V10, 0}, + { REG_V11, 0}, + { REG_V12, 0}, + { REG_V13, 0}, + { REG_V14, 0}, + { REG_V15, 0} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - W0 = address - Out - W0 = data, W1 = abrt*/ - /*MOV W1, W0, LSR #12 - MOV X2, #readlookup2 - LDR X1, [X2, X1, LSL #3] - CMP X1, #-1 - BEQ + - LDRB W0, [X1, X0] - MOV W1, #0 - RET - * STP X29, X30, [SP, #-16] - BL readmembl - LDRB R1, cpu_state.abrt - LDP X29, X30, [SP, #-16] - RET - */ - codegen_alloc(block, 80); - host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); - host_arm64_MOVX_IMM(block, REG_X2, (uint64_t)readlookup2); - host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); - if (size != 1) - { - host_arm64_TST_IMM(block, REG_W0, size-1); - misaligned_offset = host_arm64_BNE_(block); - } - host_arm64_CMPX_IMM(block, REG_X1, -1); - branch_offset = host_arm64_BEQ_(block); - if (size == 1 && !is_float) - host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 2 && !is_float) - host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4 && !is_float) - host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); - else if (size == 4 && is_float) - host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); - else if (size == 8) - host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); - host_arm64_MOVZ_IMM(block, REG_W1, 0); - host_arm64_RET(block, REG_X30); + /*In - W0 = address + Out - W0 = data, W1 = abrt*/ + /*MOV W1, W0, LSR #12 + MOV X2, #readlookup2 + LDR X1, [X2, X1, LSL #3] + CMP X1, #-1 + BEQ + + LDRB W0, [X1, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL readmembl + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + codegen_alloc(block, 80); + host_arm64_MOV_REG_LSR(block, REG_W1, REG_W0, 12); + host_arm64_MOVX_IMM(block, REG_X2, (uint64_t) readlookup2); + host_arm64_LDRX_REG_LSL3(block, REG_X1, REG_X2, REG_X1); + if (size != 1) { + host_arm64_TST_IMM(block, REG_W0, size - 1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X1, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1 && !is_float) + host_arm64_LDRB_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 2 && !is_float) + host_arm64_LDRH_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && !is_float) + host_arm64_LDR_REG(block, REG_W0, REG_W1, REG_W0); + else if (size == 4 && is_float) + host_arm64_LDR_REG_F32(block, REG_V_TEMP, REG_W1, REG_W0); + else if (size == 8) + host_arm64_LDR_REG_F64(block, REG_V_TEMP, REG_W1, REG_W0); + host_arm64_MOVZ_IMM(block, REG_W1, 0); + host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - if (size == 1) - host_arm64_call(block, (void *)readmembl); - else if (size == 2) - host_arm64_call(block, (void *)readmemwl); - else if (size == 4) - host_arm64_call(block, (void *)readmemll); - else if (size == 8) - host_arm64_call(block, (void *)readmemql); - else - fatal("build_load_routine - unknown size %i\n", size); - codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - if (size == 4 && is_float) - host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); - else if (size == 8) - host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + if (size == 1) + host_arm64_call(block, (void *) readmembl); + else if (size == 2) + host_arm64_call(block, (void *) readmemwl); + else if (size == 4) + host_arm64_call(block, (void *) readmemll); + else if (size == 8) + host_arm64_call(block, (void *) readmemql); + else + fatal("build_load_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + if (size == 4 && is_float) + host_arm64_FMOV_S_W(block, REG_V_TEMP, REG_W0); + else if (size == 8) + host_arm64_FMOV_D_Q(block, REG_V_TEMP, REG_X0); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint32_t *branch_offset; - uint32_t *misaligned_offset; + uint32_t *branch_offset; + uint32_t *misaligned_offset; - /*In - R0 = address, R1 = data - Out - R1 = abrt*/ - /*MOV W2, W0, LSR #12 - MOV X3, #writelookup2 - LDR X2, [X3, X2, LSL #3] - CMP X2, #-1 - BEQ + - STRB W1, [X2, X0] - MOV W1, #0 - RET - * STP X29, X30, [SP, #-16] - BL writemembl - LDRB R1, cpu_state.abrt - LDP X29, X30, [SP, #-16] - RET - */ - codegen_alloc(block, 80); - host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); - host_arm64_MOVX_IMM(block, REG_X3, (uint64_t)writelookup2); - host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); - if (size != 1) - { - host_arm64_TST_IMM(block, REG_W0, size-1); - misaligned_offset = host_arm64_BNE_(block); - } - host_arm64_CMPX_IMM(block, REG_X2, -1); - branch_offset = host_arm64_BEQ_(block); - if (size == 1 && !is_float) - host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 2 && !is_float) - host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4 && !is_float) - host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); - else if (size == 4 && is_float) - host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); - else if (size == 8) - host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); - host_arm64_MOVZ_IMM(block, REG_X1, 0); - host_arm64_RET(block, REG_X30); + /*In - R0 = address, R1 = data + Out - R1 = abrt*/ + /*MOV W2, W0, LSR #12 + MOV X3, #writelookup2 + LDR X2, [X3, X2, LSL #3] + CMP X2, #-1 + BEQ + + STRB W1, [X2, X0] + MOV W1, #0 + RET + * STP X29, X30, [SP, #-16] + BL writemembl + LDRB R1, cpu_state.abrt + LDP X29, X30, [SP, #-16] + RET + */ + codegen_alloc(block, 80); + host_arm64_MOV_REG_LSR(block, REG_W2, REG_W0, 12); + host_arm64_MOVX_IMM(block, REG_X3, (uint64_t) writelookup2); + host_arm64_LDRX_REG_LSL3(block, REG_X2, REG_X3, REG_X2); + if (size != 1) { + host_arm64_TST_IMM(block, REG_W0, size - 1); + misaligned_offset = host_arm64_BNE_(block); + } + host_arm64_CMPX_IMM(block, REG_X2, -1); + branch_offset = host_arm64_BEQ_(block); + if (size == 1 && !is_float) + host_arm64_STRB_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 2 && !is_float) + host_arm64_STRH_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && !is_float) + host_arm64_STR_REG(block, REG_X1, REG_X2, REG_X0); + else if (size == 4 && is_float) + host_arm64_STR_REG_F32(block, REG_V_TEMP, REG_X2, REG_X0); + else if (size == 8) + host_arm64_STR_REG_F64(block, REG_V_TEMP, REG_X2, REG_X0); + host_arm64_MOVZ_IMM(block, REG_X1, 0); + host_arm64_RET(block, REG_X30); - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - if (size != 1) - host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - if (size == 4 && is_float) - host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); - else if (size == 8) - host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); - if (size == 1) - host_arm64_call(block, (void *)writemembl); - else if (size == 2) - host_arm64_call(block, (void *)writememwl); - else if (size == 4) - host_arm64_call(block, (void *)writememll); - else if (size == 8) - host_arm64_call(block, (void *)writememql); - else - fatal("build_store_routine - unknown size %i\n", size); - codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + if (size != 1) + host_arm64_branch_set_offset(misaligned_offset, &block_write_data[block_pos]); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + if (size == 4 && is_float) + host_arm64_FMOV_W_S(block, REG_W1, REG_V_TEMP); + else if (size == 8) + host_arm64_FMOV_Q_D(block, REG_X1, REG_V_TEMP); + if (size == 1) + host_arm64_call(block, (void *) writemembl); + else if (size == 2) + host_arm64_call(block, (void *) writememwl); + else if (size == 4) + host_arm64_call(block, (void *) writememll); + else if (size == 8) + host_arm64_call(block, (void *) writememql); + else + fatal("build_store_routine - unknown size %i\n", size); + codegen_direct_read_8(block, REG_W1, &cpu_state.abrt); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &block_write_data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &block_write_data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &block_write_data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &block_write_data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &block_write_data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &block_write_data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &block_write_data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &block_write_data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &block_write_data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &block_write_data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &block_write_data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &block_write_data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &block_write_data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &block_write_data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &block_write_data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &block_write_data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &block_write_data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &block_write_data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &block_write_data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &block_write_data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &block_write_data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &block_write_data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &block_write_data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &block_write_data[block_pos]; + build_store_routine(block, 8, 1); } -static void build_fp_round_routine(codeblock_t *block, int is_quad) +static void +build_fp_round_routine(codeblock_t *block, int is_quad) { - uint64_t *jump_table; + uint64_t *jump_table; - codegen_alloc(block, 80); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.new_fp_control - (uintptr_t)&cpu_state); - host_arm64_ADR(block, REG_TEMP2, 12); - host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); - host_arm64_BR(block, REG_TEMP2); + codegen_alloc(block, 80); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.new_fp_control - (uintptr_t) &cpu_state); + host_arm64_ADR(block, REG_TEMP2, 12); + host_arm64_LDR_REG_X(block, REG_TEMP2, REG_TEMP2, REG_TEMP); + host_arm64_BR(block, REG_TEMP2); - jump_table = (uint64_t *)&block_write_data[block_pos]; - block_pos += 4*8; + jump_table = (uint64_t *) &block_write_data[block_pos]; + block_pos += 4 * 8; - jump_table[X87_ROUNDING_NEAREST] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //tie even - if (is_quad) - host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_NEAREST] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // tie even + if (is_quad) + host_arm64_FCVTNS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTNS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_UP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //pos inf - if (is_quad) - host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_UP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // pos inf + if (is_quad) + host_arm64_FCVTPS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTPS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_DOWN] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //neg inf - if (is_quad) - host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_DOWN] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // neg inf + if (is_quad) + host_arm64_FCVTMS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTMS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); - jump_table[X87_ROUNDING_CHOP] = (uint64_t)(uintptr_t)&block_write_data[block_pos]; //zero - if (is_quad) - host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); - else - host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); - host_arm64_RET(block, REG_X30); + jump_table[X87_ROUNDING_CHOP] = (uint64_t) (uintptr_t) &block_write_data[block_pos]; // zero + if (is_quad) + host_arm64_FCVTZS_X_D(block, REG_TEMP, REG_V_TEMP); + else + host_arm64_FCVTZS_W_D(block, REG_TEMP, REG_V_TEMP); + host_arm64_RET(block, REG_X30); } -void codegen_backend_init(void) +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - { - codeblock[c].pc = BLOCK_PC_INVALID; - } + for (c = 0; c < BLOCK_SIZE; c++) { + codeblock[c].pc = BLOCK_PC_INVALID; + } - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(block); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_fp_round = &block_write_data[block_pos]; - build_fp_round_routine(block, 0); - codegen_fp_round_quad = &block_write_data[block_pos]; - build_fp_round_routine(block, 1); + codegen_fp_round = &block_write_data[block_pos]; + build_fp_round_routine(block, 0); + codegen_fp_round_quad = &block_write_data[block_pos]; + build_fp_round_routine(block, 1); - codegen_alloc(block, 80); - codegen_gpf_rout = &block_write_data[block_pos]; - host_arm64_mov_imm(block, REG_ARG0, 0); - host_arm64_mov_imm(block, REG_ARG1, 0); - host_arm64_call(block, (void *)x86gpf); + codegen_alloc(block, 80); + codegen_gpf_rout = &block_write_data[block_pos]; + host_arm64_mov_imm(block, REG_ARG0, 0); + host_arm64_mov_imm(block, REG_ARG1, 0); + host_arm64_call(block, (void *) x86gpf); - codegen_exit_rout = &block_write_data[block_pos]; - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + codegen_exit_rout = &block_write_data[block_pos]; + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); - block_write_data = NULL; + block_write_data = NULL; - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); - asm("mrs %0, fpcr\n" - : "=r" (cpu_state.old_fp_control) - ); + asm("mrs %0, fpcr\n" + : "=r"(cpu_state.old_fp_control)); } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - if (mode < 0 || mode > 3) - fatal("codegen_set_rounding_mode - invalid mode\n"); - cpu_state.new_fp_control = mode << 3; + if (mode < 0 || mode > 3) + fatal("codegen_set_rounding_mode - invalid mode\n"); + cpu_state.new_fp_control = mode << 3; } /*R10 - cpu_state*/ -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; + block_pos = BLOCK_START; - /*Entry code*/ + /*Entry code*/ - host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); - host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); + host_arm64_STP_PREIDX_X(block, REG_X29, REG_X30, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X27, REG_X28, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X25, REG_X26, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X23, REG_X24, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X21, REG_X22, REG_XSP, -16); + host_arm64_STP_PREIDX_X(block, REG_X19, REG_X20, REG_XSP, -64); - host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t)&cpu_state); + host_arm64_MOVX_IMM(block, REG_CPUSTATE, (uint64_t) &cpu_state); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - } + if (block->flags & CODEBLOCK_HAS_FPU) { + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm64_SUB_IMM(block, REG_TEMP, REG_TEMP, block->TOP); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + } } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); - host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); - host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); - host_arm64_RET(block, REG_X30); + host_arm64_LDP_POSTIDX_X(block, REG_X19, REG_X20, REG_XSP, 64); + host_arm64_LDP_POSTIDX_X(block, REG_X21, REG_X22, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X23, REG_X24, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X25, REG_X26, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X27, REG_X28, REG_XSP, 16); + host_arm64_LDP_POSTIDX_X(block, REG_X29, REG_X30, REG_XSP, 16); + host_arm64_RET(block, REG_X30); - codegen_allocator_clean_blocks(block->head_mem_block); + codegen_allocator_clean_blocks(block->head_mem_block); } #endif diff --git a/src/codegen_new/codegen_backend_arm64.h b/src/codegen_new/codegen_backend_arm64.h index 3e3d16575..bf3084f58 100644 --- a/src/codegen_new/codegen_backend_arm64.h +++ b/src/codegen_new/codegen_backend_arm64.h @@ -1,16 +1,15 @@ #include "codegen_backend_arm64_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) - -#define BLOCK_MAX 0x3c0 +#define HASH(l) ((l) &0x1ffff) +#define BLOCK_MAX 0x3c0 void host_arm64_BLR(codeblock_t *block, int addr_reg); void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest); diff --git a/src/codegen_new/codegen_backend_arm64_defs.h b/src/codegen_new/codegen_backend_arm64_defs.h index ac2d238da..c36f1c4a2 100644 --- a/src/codegen_new/codegen_backend_arm64_defs.h +++ b/src/codegen_new/codegen_backend_arm64_defs.h @@ -1,117 +1,117 @@ -#define REG_W0 0 -#define REG_W1 1 -#define REG_W2 2 -#define REG_W3 3 -#define REG_W4 4 -#define REG_W5 5 -#define REG_W6 6 -#define REG_W7 7 -#define REG_W8 8 -#define REG_W9 9 -#define REG_W10 10 -#define REG_W11 11 -#define REG_W12 12 -#define REG_W13 13 -#define REG_W14 14 -#define REG_W15 15 -#define REG_W16 16 -#define REG_W17 17 -#define REG_W18 18 -#define REG_W19 19 -#define REG_W20 20 -#define REG_W21 21 -#define REG_W22 22 -#define REG_W23 23 -#define REG_W24 24 -#define REG_W25 25 -#define REG_W26 26 -#define REG_W27 27 -#define REG_W28 28 -#define REG_W29 29 -#define REG_W30 30 -#define REG_WZR 31 +#define REG_W0 0 +#define REG_W1 1 +#define REG_W2 2 +#define REG_W3 3 +#define REG_W4 4 +#define REG_W5 5 +#define REG_W6 6 +#define REG_W7 7 +#define REG_W8 8 +#define REG_W9 9 +#define REG_W10 10 +#define REG_W11 11 +#define REG_W12 12 +#define REG_W13 13 +#define REG_W14 14 +#define REG_W15 15 +#define REG_W16 16 +#define REG_W17 17 +#define REG_W18 18 +#define REG_W19 19 +#define REG_W20 20 +#define REG_W21 21 +#define REG_W22 22 +#define REG_W23 23 +#define REG_W24 24 +#define REG_W25 25 +#define REG_W26 26 +#define REG_W27 27 +#define REG_W28 28 +#define REG_W29 29 +#define REG_W30 30 +#define REG_WZR 31 -#define REG_X0 0 -#define REG_X1 1 -#define REG_X2 2 -#define REG_X3 3 -#define REG_X4 4 -#define REG_X5 5 -#define REG_X6 6 -#define REG_X7 7 -#define REG_X8 8 -#define REG_X9 9 -#define REG_X10 10 -#define REG_X11 11 -#define REG_X12 12 -#define REG_X13 13 -#define REG_X14 14 -#define REG_X15 15 -#define REG_X16 16 -#define REG_X17 17 -#define REG_X18 18 -#define REG_X19 19 -#define REG_X20 20 -#define REG_X21 21 -#define REG_X22 22 -#define REG_X23 23 -#define REG_X24 24 -#define REG_X25 25 -#define REG_X26 26 -#define REG_X27 27 -#define REG_X28 28 -#define REG_X29 29 -#define REG_X30 30 -#define REG_XZR 31 +#define REG_X0 0 +#define REG_X1 1 +#define REG_X2 2 +#define REG_X3 3 +#define REG_X4 4 +#define REG_X5 5 +#define REG_X6 6 +#define REG_X7 7 +#define REG_X8 8 +#define REG_X9 9 +#define REG_X10 10 +#define REG_X11 11 +#define REG_X12 12 +#define REG_X13 13 +#define REG_X14 14 +#define REG_X15 15 +#define REG_X16 16 +#define REG_X17 17 +#define REG_X18 18 +#define REG_X19 19 +#define REG_X20 20 +#define REG_X21 21 +#define REG_X22 22 +#define REG_X23 23 +#define REG_X24 24 +#define REG_X25 25 +#define REG_X26 26 +#define REG_X27 27 +#define REG_X28 28 +#define REG_X29 29 +#define REG_X30 30 +#define REG_XZR 31 -#define REG_V0 0 -#define REG_V1 1 -#define REG_V2 2 -#define REG_V3 3 -#define REG_V4 4 -#define REG_V5 5 -#define REG_V6 6 -#define REG_V7 7 -#define REG_V8 8 -#define REG_V9 9 -#define REG_V10 10 -#define REG_V11 11 -#define REG_V12 12 -#define REG_V13 13 -#define REG_V14 14 -#define REG_V15 15 -#define REG_V16 16 -#define REG_V17 17 -#define REG_V18 18 -#define REG_V19 19 -#define REG_V20 20 -#define REG_V21 21 -#define REG_V22 22 -#define REG_V23 23 -#define REG_V24 24 -#define REG_V25 25 -#define REG_V26 26 -#define REG_V27 27 -#define REG_V28 28 -#define REG_V29 29 -#define REG_V30 30 -#define REG_V31 31 +#define REG_V0 0 +#define REG_V1 1 +#define REG_V2 2 +#define REG_V3 3 +#define REG_V4 4 +#define REG_V5 5 +#define REG_V6 6 +#define REG_V7 7 +#define REG_V8 8 +#define REG_V9 9 +#define REG_V10 10 +#define REG_V11 11 +#define REG_V12 12 +#define REG_V13 13 +#define REG_V14 14 +#define REG_V15 15 +#define REG_V16 16 +#define REG_V17 17 +#define REG_V18 18 +#define REG_V19 19 +#define REG_V20 20 +#define REG_V21 21 +#define REG_V22 22 +#define REG_V23 23 +#define REG_V24 24 +#define REG_V25 25 +#define REG_V26 26 +#define REG_V27 27 +#define REG_V28 28 +#define REG_V29 29 +#define REG_V30 30 +#define REG_V31 31 -#define REG_XSP 31 +#define REG_XSP 31 -#define REG_ARG0 REG_X0 -#define REG_ARG1 REG_X1 -#define REG_ARG2 REG_X2 -#define REG_ARG3 REG_X3 +#define REG_ARG0 REG_X0 +#define REG_ARG1 REG_X1 +#define REG_ARG2 REG_X2 +#define REG_ARG3 REG_X3 -#define REG_CPUSTATE REG_X29 +#define REG_CPUSTATE REG_X29 -#define REG_TEMP REG_X7 -#define REG_TEMP2 REG_X6 +#define REG_TEMP REG_X7 +#define REG_TEMP2 REG_X6 -#define REG_V_TEMP REG_V0 +#define REG_V_TEMP REG_V0 -#define CODEGEN_HOST_REGS 10 +#define CODEGEN_HOST_REGS 10 #define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_arm64_imm.c b/src/codegen_new/codegen_backend_arm64_imm.c index 0362b71d6..5e1e1038f 100644 --- a/src/codegen_new/codegen_backend_arm64_imm.c +++ b/src/codegen_new/codegen_backend_arm64_imm.c @@ -5,1326 +5,1325 @@ All valid values are in the table below, which we perform a binary search over*/ #define IMM_NR 1302 -static uint32_t imm_table[][2] = -{ - {0x800, 0x00000001}, - {0xfc0, 0x00000002}, - {0x801, 0x00000003}, - {0xf80, 0x00000004}, - {0xfc1, 0x00000006}, - {0x802, 0x00000007}, - {0xf40, 0x00000008}, - {0xf81, 0x0000000c}, - {0xfc2, 0x0000000e}, - {0x803, 0x0000000f}, - {0xf00, 0x00000010}, - {0xf41, 0x00000018}, - {0xf82, 0x0000001c}, - {0xfc3, 0x0000001e}, - {0x804, 0x0000001f}, - {0xec0, 0x00000020}, - {0xf01, 0x00000030}, - {0xf42, 0x00000038}, - {0xf83, 0x0000003c}, - {0xfc4, 0x0000003e}, - {0x805, 0x0000003f}, - {0xe80, 0x00000040}, - {0xec1, 0x00000060}, - {0xf02, 0x00000070}, - {0xf43, 0x00000078}, - {0xf84, 0x0000007c}, - {0xfc5, 0x0000007e}, - {0x806, 0x0000007f}, - {0xe40, 0x00000080}, - {0xe81, 0x000000c0}, - {0xec2, 0x000000e0}, - {0xf03, 0x000000f0}, - {0xf44, 0x000000f8}, - {0xf85, 0x000000fc}, - {0xfc6, 0x000000fe}, - {0x807, 0x000000ff}, - {0xe00, 0x00000100}, - {0xe41, 0x00000180}, - {0xe82, 0x000001c0}, - {0xec3, 0x000001e0}, - {0xf04, 0x000001f0}, - {0xf45, 0x000001f8}, - {0xf86, 0x000001fc}, - {0xfc7, 0x000001fe}, - {0x808, 0x000001ff}, - {0xdc0, 0x00000200}, - {0xe01, 0x00000300}, - {0xe42, 0x00000380}, - {0xe83, 0x000003c0}, - {0xec4, 0x000003e0}, - {0xf05, 0x000003f0}, - {0xf46, 0x000003f8}, - {0xf87, 0x000003fc}, - {0xfc8, 0x000003fe}, - {0x809, 0x000003ff}, - {0xd80, 0x00000400}, - {0xdc1, 0x00000600}, - {0xe02, 0x00000700}, - {0xe43, 0x00000780}, - {0xe84, 0x000007c0}, - {0xec5, 0x000007e0}, - {0xf06, 0x000007f0}, - {0xf47, 0x000007f8}, - {0xf88, 0x000007fc}, - {0xfc9, 0x000007fe}, - {0x80a, 0x000007ff}, - {0xd40, 0x00000800}, - {0xd81, 0x00000c00}, - {0xdc2, 0x00000e00}, - {0xe03, 0x00000f00}, - {0xe44, 0x00000f80}, - {0xe85, 0x00000fc0}, - {0xec6, 0x00000fe0}, - {0xf07, 0x00000ff0}, - {0xf48, 0x00000ff8}, - {0xf89, 0x00000ffc}, - {0xfca, 0x00000ffe}, - {0x80b, 0x00000fff}, - {0xd00, 0x00001000}, - {0xd41, 0x00001800}, - {0xd82, 0x00001c00}, - {0xdc3, 0x00001e00}, - {0xe04, 0x00001f00}, - {0xe45, 0x00001f80}, - {0xe86, 0x00001fc0}, - {0xec7, 0x00001fe0}, - {0xf08, 0x00001ff0}, - {0xf49, 0x00001ff8}, - {0xf8a, 0x00001ffc}, - {0xfcb, 0x00001ffe}, - {0x80c, 0x00001fff}, - {0xcc0, 0x00002000}, - {0xd01, 0x00003000}, - {0xd42, 0x00003800}, - {0xd83, 0x00003c00}, - {0xdc4, 0x00003e00}, - {0xe05, 0x00003f00}, - {0xe46, 0x00003f80}, - {0xe87, 0x00003fc0}, - {0xec8, 0x00003fe0}, - {0xf09, 0x00003ff0}, - {0xf4a, 0x00003ff8}, - {0xf8b, 0x00003ffc}, - {0xfcc, 0x00003ffe}, - {0x80d, 0x00003fff}, - {0xc80, 0x00004000}, - {0xcc1, 0x00006000}, - {0xd02, 0x00007000}, - {0xd43, 0x00007800}, - {0xd84, 0x00007c00}, - {0xdc5, 0x00007e00}, - {0xe06, 0x00007f00}, - {0xe47, 0x00007f80}, - {0xe88, 0x00007fc0}, - {0xec9, 0x00007fe0}, - {0xf0a, 0x00007ff0}, - {0xf4b, 0x00007ff8}, - {0xf8c, 0x00007ffc}, - {0xfcd, 0x00007ffe}, - {0x80e, 0x00007fff}, - {0xc40, 0x00008000}, - {0xc81, 0x0000c000}, - {0xcc2, 0x0000e000}, - {0xd03, 0x0000f000}, - {0xd44, 0x0000f800}, - {0xd85, 0x0000fc00}, - {0xdc6, 0x0000fe00}, - {0xe07, 0x0000ff00}, - {0xe48, 0x0000ff80}, - {0xe89, 0x0000ffc0}, - {0xeca, 0x0000ffe0}, - {0xf0b, 0x0000fff0}, - {0xf4c, 0x0000fff8}, - {0xf8d, 0x0000fffc}, - {0xfce, 0x0000fffe}, - {0x80f, 0x0000ffff}, - {0xc00, 0x00010000}, - {0xc20, 0x00010001}, - {0xc41, 0x00018000}, - {0xc82, 0x0001c000}, - {0xcc3, 0x0001e000}, - {0xd04, 0x0001f000}, - {0xd45, 0x0001f800}, - {0xd86, 0x0001fc00}, - {0xdc7, 0x0001fe00}, - {0xe08, 0x0001ff00}, - {0xe49, 0x0001ff80}, - {0xe8a, 0x0001ffc0}, - {0xecb, 0x0001ffe0}, - {0xf0c, 0x0001fff0}, - {0xf4d, 0x0001fff8}, - {0xf8e, 0x0001fffc}, - {0xfcf, 0x0001fffe}, - {0x810, 0x0001ffff}, - {0xbc0, 0x00020000}, - {0xfe0, 0x00020002}, - {0xc01, 0x00030000}, - {0xc21, 0x00030003}, - {0xc42, 0x00038000}, - {0xc83, 0x0003c000}, - {0xcc4, 0x0003e000}, - {0xd05, 0x0003f000}, - {0xd46, 0x0003f800}, - {0xd87, 0x0003fc00}, - {0xdc8, 0x0003fe00}, - {0xe09, 0x0003ff00}, - {0xe4a, 0x0003ff80}, - {0xe8b, 0x0003ffc0}, - {0xecc, 0x0003ffe0}, - {0xf0d, 0x0003fff0}, - {0xf4e, 0x0003fff8}, - {0xf8f, 0x0003fffc}, - {0xfd0, 0x0003fffe}, - {0x811, 0x0003ffff}, - {0xb80, 0x00040000}, - {0xfa0, 0x00040004}, - {0xbc1, 0x00060000}, - {0xfe1, 0x00060006}, - {0xc02, 0x00070000}, - {0xc22, 0x00070007}, - {0xc43, 0x00078000}, - {0xc84, 0x0007c000}, - {0xcc5, 0x0007e000}, - {0xd06, 0x0007f000}, - {0xd47, 0x0007f800}, - {0xd88, 0x0007fc00}, - {0xdc9, 0x0007fe00}, - {0xe0a, 0x0007ff00}, - {0xe4b, 0x0007ff80}, - {0xe8c, 0x0007ffc0}, - {0xecd, 0x0007ffe0}, - {0xf0e, 0x0007fff0}, - {0xf4f, 0x0007fff8}, - {0xf90, 0x0007fffc}, - {0xfd1, 0x0007fffe}, - {0x812, 0x0007ffff}, - {0xb40, 0x00080000}, - {0xf60, 0x00080008}, - {0xb81, 0x000c0000}, - {0xfa1, 0x000c000c}, - {0xbc2, 0x000e0000}, - {0xfe2, 0x000e000e}, - {0xc03, 0x000f0000}, - {0xc23, 0x000f000f}, - {0xc44, 0x000f8000}, - {0xc85, 0x000fc000}, - {0xcc6, 0x000fe000}, - {0xd07, 0x000ff000}, - {0xd48, 0x000ff800}, - {0xd89, 0x000ffc00}, - {0xdca, 0x000ffe00}, - {0xe0b, 0x000fff00}, - {0xe4c, 0x000fff80}, - {0xe8d, 0x000fffc0}, - {0xece, 0x000fffe0}, - {0xf0f, 0x000ffff0}, - {0xf50, 0x000ffff8}, - {0xf91, 0x000ffffc}, - {0xfd2, 0x000ffffe}, - {0x813, 0x000fffff}, - {0xb00, 0x00100000}, - {0xf20, 0x00100010}, - {0xb41, 0x00180000}, - {0xf61, 0x00180018}, - {0xb82, 0x001c0000}, - {0xfa2, 0x001c001c}, - {0xbc3, 0x001e0000}, - {0xfe3, 0x001e001e}, - {0xc04, 0x001f0000}, - {0xc24, 0x001f001f}, - {0xc45, 0x001f8000}, - {0xc86, 0x001fc000}, - {0xcc7, 0x001fe000}, - {0xd08, 0x001ff000}, - {0xd49, 0x001ff800}, - {0xd8a, 0x001ffc00}, - {0xdcb, 0x001ffe00}, - {0xe0c, 0x001fff00}, - {0xe4d, 0x001fff80}, - {0xe8e, 0x001fffc0}, - {0xecf, 0x001fffe0}, - {0xf10, 0x001ffff0}, - {0xf51, 0x001ffff8}, - {0xf92, 0x001ffffc}, - {0xfd3, 0x001ffffe}, - {0x814, 0x001fffff}, - {0xac0, 0x00200000}, - {0xee0, 0x00200020}, - {0xb01, 0x00300000}, - {0xf21, 0x00300030}, - {0xb42, 0x00380000}, - {0xf62, 0x00380038}, - {0xb83, 0x003c0000}, - {0xfa3, 0x003c003c}, - {0xbc4, 0x003e0000}, - {0xfe4, 0x003e003e}, - {0xc05, 0x003f0000}, - {0xc25, 0x003f003f}, - {0xc46, 0x003f8000}, - {0xc87, 0x003fc000}, - {0xcc8, 0x003fe000}, - {0xd09, 0x003ff000}, - {0xd4a, 0x003ff800}, - {0xd8b, 0x003ffc00}, - {0xdcc, 0x003ffe00}, - {0xe0d, 0x003fff00}, - {0xe4e, 0x003fff80}, - {0xe8f, 0x003fffc0}, - {0xed0, 0x003fffe0}, - {0xf11, 0x003ffff0}, - {0xf52, 0x003ffff8}, - {0xf93, 0x003ffffc}, - {0xfd4, 0x003ffffe}, - {0x815, 0x003fffff}, - {0xa80, 0x00400000}, - {0xea0, 0x00400040}, - {0xac1, 0x00600000}, - {0xee1, 0x00600060}, - {0xb02, 0x00700000}, - {0xf22, 0x00700070}, - {0xb43, 0x00780000}, - {0xf63, 0x00780078}, - {0xb84, 0x007c0000}, - {0xfa4, 0x007c007c}, - {0xbc5, 0x007e0000}, - {0xfe5, 0x007e007e}, - {0xc06, 0x007f0000}, - {0xc26, 0x007f007f}, - {0xc47, 0x007f8000}, - {0xc88, 0x007fc000}, - {0xcc9, 0x007fe000}, - {0xd0a, 0x007ff000}, - {0xd4b, 0x007ff800}, - {0xd8c, 0x007ffc00}, - {0xdcd, 0x007ffe00}, - {0xe0e, 0x007fff00}, - {0xe4f, 0x007fff80}, - {0xe90, 0x007fffc0}, - {0xed1, 0x007fffe0}, - {0xf12, 0x007ffff0}, - {0xf53, 0x007ffff8}, - {0xf94, 0x007ffffc}, - {0xfd5, 0x007ffffe}, - {0x816, 0x007fffff}, - {0xa40, 0x00800000}, - {0xe60, 0x00800080}, - {0xa81, 0x00c00000}, - {0xea1, 0x00c000c0}, - {0xac2, 0x00e00000}, - {0xee2, 0x00e000e0}, - {0xb03, 0x00f00000}, - {0xf23, 0x00f000f0}, - {0xb44, 0x00f80000}, - {0xf64, 0x00f800f8}, - {0xb85, 0x00fc0000}, - {0xfa5, 0x00fc00fc}, - {0xbc6, 0x00fe0000}, - {0xfe6, 0x00fe00fe}, - {0xc07, 0x00ff0000}, - {0xc27, 0x00ff00ff}, - {0xc48, 0x00ff8000}, - {0xc89, 0x00ffc000}, - {0xcca, 0x00ffe000}, - {0xd0b, 0x00fff000}, - {0xd4c, 0x00fff800}, - {0xd8d, 0x00fffc00}, - {0xdce, 0x00fffe00}, - {0xe0f, 0x00ffff00}, - {0xe50, 0x00ffff80}, - {0xe91, 0x00ffffc0}, - {0xed2, 0x00ffffe0}, - {0xf13, 0x00fffff0}, - {0xf54, 0x00fffff8}, - {0xf95, 0x00fffffc}, - {0xfd6, 0x00fffffe}, - {0x817, 0x00ffffff}, - {0xa00, 0x01000000}, - {0xe20, 0x01000100}, - {0xe30, 0x01010101}, - {0xa41, 0x01800000}, - {0xe61, 0x01800180}, - {0xa82, 0x01c00000}, - {0xea2, 0x01c001c0}, - {0xac3, 0x01e00000}, - {0xee3, 0x01e001e0}, - {0xb04, 0x01f00000}, - {0xf24, 0x01f001f0}, - {0xb45, 0x01f80000}, - {0xf65, 0x01f801f8}, - {0xb86, 0x01fc0000}, - {0xfa6, 0x01fc01fc}, - {0xbc7, 0x01fe0000}, - {0xfe7, 0x01fe01fe}, - {0xc08, 0x01ff0000}, - {0xc28, 0x01ff01ff}, - {0xc49, 0x01ff8000}, - {0xc8a, 0x01ffc000}, - {0xccb, 0x01ffe000}, - {0xd0c, 0x01fff000}, - {0xd4d, 0x01fff800}, - {0xd8e, 0x01fffc00}, - {0xdcf, 0x01fffe00}, - {0xe10, 0x01ffff00}, - {0xe51, 0x01ffff80}, - {0xe92, 0x01ffffc0}, - {0xed3, 0x01ffffe0}, - {0xf14, 0x01fffff0}, - {0xf55, 0x01fffff8}, - {0xf96, 0x01fffffc}, - {0xfd7, 0x01fffffe}, - {0x818, 0x01ffffff}, - {0x9c0, 0x02000000}, - {0xde0, 0x02000200}, - {0xff0, 0x02020202}, - {0xa01, 0x03000000}, - {0xe21, 0x03000300}, - {0xe31, 0x03030303}, - {0xa42, 0x03800000}, - {0xe62, 0x03800380}, - {0xa83, 0x03c00000}, - {0xea3, 0x03c003c0}, - {0xac4, 0x03e00000}, - {0xee4, 0x03e003e0}, - {0xb05, 0x03f00000}, - {0xf25, 0x03f003f0}, - {0xb46, 0x03f80000}, - {0xf66, 0x03f803f8}, - {0xb87, 0x03fc0000}, - {0xfa7, 0x03fc03fc}, - {0xbc8, 0x03fe0000}, - {0xfe8, 0x03fe03fe}, - {0xc09, 0x03ff0000}, - {0xc29, 0x03ff03ff}, - {0xc4a, 0x03ff8000}, - {0xc8b, 0x03ffc000}, - {0xccc, 0x03ffe000}, - {0xd0d, 0x03fff000}, - {0xd4e, 0x03fff800}, - {0xd8f, 0x03fffc00}, - {0xdd0, 0x03fffe00}, - {0xe11, 0x03ffff00}, - {0xe52, 0x03ffff80}, - {0xe93, 0x03ffffc0}, - {0xed4, 0x03ffffe0}, - {0xf15, 0x03fffff0}, - {0xf56, 0x03fffff8}, - {0xf97, 0x03fffffc}, - {0xfd8, 0x03fffffe}, - {0x819, 0x03ffffff}, - {0x980, 0x04000000}, - {0xda0, 0x04000400}, - {0xfb0, 0x04040404}, - {0x9c1, 0x06000000}, - {0xde1, 0x06000600}, - {0xff1, 0x06060606}, - {0xa02, 0x07000000}, - {0xe22, 0x07000700}, - {0xe32, 0x07070707}, - {0xa43, 0x07800000}, - {0xe63, 0x07800780}, - {0xa84, 0x07c00000}, - {0xea4, 0x07c007c0}, - {0xac5, 0x07e00000}, - {0xee5, 0x07e007e0}, - {0xb06, 0x07f00000}, - {0xf26, 0x07f007f0}, - {0xb47, 0x07f80000}, - {0xf67, 0x07f807f8}, - {0xb88, 0x07fc0000}, - {0xfa8, 0x07fc07fc}, - {0xbc9, 0x07fe0000}, - {0xfe9, 0x07fe07fe}, - {0xc0a, 0x07ff0000}, - {0xc2a, 0x07ff07ff}, - {0xc4b, 0x07ff8000}, - {0xc8c, 0x07ffc000}, - {0xccd, 0x07ffe000}, - {0xd0e, 0x07fff000}, - {0xd4f, 0x07fff800}, - {0xd90, 0x07fffc00}, - {0xdd1, 0x07fffe00}, - {0xe12, 0x07ffff00}, - {0xe53, 0x07ffff80}, - {0xe94, 0x07ffffc0}, - {0xed5, 0x07ffffe0}, - {0xf16, 0x07fffff0}, - {0xf57, 0x07fffff8}, - {0xf98, 0x07fffffc}, - {0xfd9, 0x07fffffe}, - {0x81a, 0x07ffffff}, - {0x940, 0x08000000}, - {0xd60, 0x08000800}, - {0xf70, 0x08080808}, - {0x981, 0x0c000000}, - {0xda1, 0x0c000c00}, - {0xfb1, 0x0c0c0c0c}, - {0x9c2, 0x0e000000}, - {0xde2, 0x0e000e00}, - {0xff2, 0x0e0e0e0e}, - {0xa03, 0x0f000000}, - {0xe23, 0x0f000f00}, - {0xe33, 0x0f0f0f0f}, - {0xa44, 0x0f800000}, - {0xe64, 0x0f800f80}, - {0xa85, 0x0fc00000}, - {0xea5, 0x0fc00fc0}, - {0xac6, 0x0fe00000}, - {0xee6, 0x0fe00fe0}, - {0xb07, 0x0ff00000}, - {0xf27, 0x0ff00ff0}, - {0xb48, 0x0ff80000}, - {0xf68, 0x0ff80ff8}, - {0xb89, 0x0ffc0000}, - {0xfa9, 0x0ffc0ffc}, - {0xbca, 0x0ffe0000}, - {0xfea, 0x0ffe0ffe}, - {0xc0b, 0x0fff0000}, - {0xc2b, 0x0fff0fff}, - {0xc4c, 0x0fff8000}, - {0xc8d, 0x0fffc000}, - {0xcce, 0x0fffe000}, - {0xd0f, 0x0ffff000}, - {0xd50, 0x0ffff800}, - {0xd91, 0x0ffffc00}, - {0xdd2, 0x0ffffe00}, - {0xe13, 0x0fffff00}, - {0xe54, 0x0fffff80}, - {0xe95, 0x0fffffc0}, - {0xed6, 0x0fffffe0}, - {0xf17, 0x0ffffff0}, - {0xf58, 0x0ffffff8}, - {0xf99, 0x0ffffffc}, - {0xfda, 0x0ffffffe}, - {0x81b, 0x0fffffff}, - {0x900, 0x10000000}, - {0xd20, 0x10001000}, - {0xf30, 0x10101010}, - {0xf38, 0x11111111}, - {0x941, 0x18000000}, - {0xd61, 0x18001800}, - {0xf71, 0x18181818}, - {0x982, 0x1c000000}, - {0xda2, 0x1c001c00}, - {0xfb2, 0x1c1c1c1c}, - {0x9c3, 0x1e000000}, - {0xde3, 0x1e001e00}, - {0xff3, 0x1e1e1e1e}, - {0xa04, 0x1f000000}, - {0xe24, 0x1f001f00}, - {0xe34, 0x1f1f1f1f}, - {0xa45, 0x1f800000}, - {0xe65, 0x1f801f80}, - {0xa86, 0x1fc00000}, - {0xea6, 0x1fc01fc0}, - {0xac7, 0x1fe00000}, - {0xee7, 0x1fe01fe0}, - {0xb08, 0x1ff00000}, - {0xf28, 0x1ff01ff0}, - {0xb49, 0x1ff80000}, - {0xf69, 0x1ff81ff8}, - {0xb8a, 0x1ffc0000}, - {0xfaa, 0x1ffc1ffc}, - {0xbcb, 0x1ffe0000}, - {0xfeb, 0x1ffe1ffe}, - {0xc0c, 0x1fff0000}, - {0xc2c, 0x1fff1fff}, - {0xc4d, 0x1fff8000}, - {0xc8e, 0x1fffc000}, - {0xccf, 0x1fffe000}, - {0xd10, 0x1ffff000}, - {0xd51, 0x1ffff800}, - {0xd92, 0x1ffffc00}, - {0xdd3, 0x1ffffe00}, - {0xe14, 0x1fffff00}, - {0xe55, 0x1fffff80}, - {0xe96, 0x1fffffc0}, - {0xed7, 0x1fffffe0}, - {0xf18, 0x1ffffff0}, - {0xf59, 0x1ffffff8}, - {0xf9a, 0x1ffffffc}, - {0xfdb, 0x1ffffffe}, - {0x81c, 0x1fffffff}, - {0x8c0, 0x20000000}, - {0xce0, 0x20002000}, - {0xef0, 0x20202020}, - {0xff8, 0x22222222}, - {0x901, 0x30000000}, - {0xd21, 0x30003000}, - {0xf31, 0x30303030}, - {0xf39, 0x33333333}, - {0x942, 0x38000000}, - {0xd62, 0x38003800}, - {0xf72, 0x38383838}, - {0x983, 0x3c000000}, - {0xda3, 0x3c003c00}, - {0xfb3, 0x3c3c3c3c}, - {0x9c4, 0x3e000000}, - {0xde4, 0x3e003e00}, - {0xff4, 0x3e3e3e3e}, - {0xa05, 0x3f000000}, - {0xe25, 0x3f003f00}, - {0xe35, 0x3f3f3f3f}, - {0xa46, 0x3f800000}, - {0xe66, 0x3f803f80}, - {0xa87, 0x3fc00000}, - {0xea7, 0x3fc03fc0}, - {0xac8, 0x3fe00000}, - {0xee8, 0x3fe03fe0}, - {0xb09, 0x3ff00000}, - {0xf29, 0x3ff03ff0}, - {0xb4a, 0x3ff80000}, - {0xf6a, 0x3ff83ff8}, - {0xb8b, 0x3ffc0000}, - {0xfab, 0x3ffc3ffc}, - {0xbcc, 0x3ffe0000}, - {0xfec, 0x3ffe3ffe}, - {0xc0d, 0x3fff0000}, - {0xc2d, 0x3fff3fff}, - {0xc4e, 0x3fff8000}, - {0xc8f, 0x3fffc000}, - {0xcd0, 0x3fffe000}, - {0xd11, 0x3ffff000}, - {0xd52, 0x3ffff800}, - {0xd93, 0x3ffffc00}, - {0xdd4, 0x3ffffe00}, - {0xe15, 0x3fffff00}, - {0xe56, 0x3fffff80}, - {0xe97, 0x3fffffc0}, - {0xed8, 0x3fffffe0}, - {0xf19, 0x3ffffff0}, - {0xf5a, 0x3ffffff8}, - {0xf9b, 0x3ffffffc}, - {0xfdc, 0x3ffffffe}, - {0x81d, 0x3fffffff}, - {0x880, 0x40000000}, - {0xca0, 0x40004000}, - {0xeb0, 0x40404040}, - {0xfb8, 0x44444444}, - {0xfbc, 0x55555555}, - {0x8c1, 0x60000000}, - {0xce1, 0x60006000}, - {0xef1, 0x60606060}, - {0xff9, 0x66666666}, - {0x902, 0x70000000}, - {0xd22, 0x70007000}, - {0xf32, 0x70707070}, - {0xf3a, 0x77777777}, - {0x943, 0x78000000}, - {0xd63, 0x78007800}, - {0xf73, 0x78787878}, - {0x984, 0x7c000000}, - {0xda4, 0x7c007c00}, - {0xfb4, 0x7c7c7c7c}, - {0x9c5, 0x7e000000}, - {0xde5, 0x7e007e00}, - {0xff5, 0x7e7e7e7e}, - {0xa06, 0x7f000000}, - {0xe26, 0x7f007f00}, - {0xe36, 0x7f7f7f7f}, - {0xa47, 0x7f800000}, - {0xe67, 0x7f807f80}, - {0xa88, 0x7fc00000}, - {0xea8, 0x7fc07fc0}, - {0xac9, 0x7fe00000}, - {0xee9, 0x7fe07fe0}, - {0xb0a, 0x7ff00000}, - {0xf2a, 0x7ff07ff0}, - {0xb4b, 0x7ff80000}, - {0xf6b, 0x7ff87ff8}, - {0xb8c, 0x7ffc0000}, - {0xfac, 0x7ffc7ffc}, - {0xbcd, 0x7ffe0000}, - {0xfed, 0x7ffe7ffe}, - {0xc0e, 0x7fff0000}, - {0xc2e, 0x7fff7fff}, - {0xc4f, 0x7fff8000}, - {0xc90, 0x7fffc000}, - {0xcd1, 0x7fffe000}, - {0xd12, 0x7ffff000}, - {0xd53, 0x7ffff800}, - {0xd94, 0x7ffffc00}, - {0xdd5, 0x7ffffe00}, - {0xe16, 0x7fffff00}, - {0xe57, 0x7fffff80}, - {0xe98, 0x7fffffc0}, - {0xed9, 0x7fffffe0}, - {0xf1a, 0x7ffffff0}, - {0xf5b, 0x7ffffff8}, - {0xf9c, 0x7ffffffc}, - {0xfdd, 0x7ffffffe}, - {0x81e, 0x7fffffff}, - {0x840, 0x80000000}, - {0x841, 0x80000001}, - {0x842, 0x80000003}, - {0x843, 0x80000007}, - {0x844, 0x8000000f}, - {0x845, 0x8000001f}, - {0x846, 0x8000003f}, - {0x847, 0x8000007f}, - {0x848, 0x800000ff}, - {0x849, 0x800001ff}, - {0x84a, 0x800003ff}, - {0x84b, 0x800007ff}, - {0x84c, 0x80000fff}, - {0x84d, 0x80001fff}, - {0x84e, 0x80003fff}, - {0x84f, 0x80007fff}, - {0xc60, 0x80008000}, - {0x850, 0x8000ffff}, - {0xc61, 0x80018001}, - {0x851, 0x8001ffff}, - {0xc62, 0x80038003}, - {0x852, 0x8003ffff}, - {0xc63, 0x80078007}, - {0x853, 0x8007ffff}, - {0xc64, 0x800f800f}, - {0x854, 0x800fffff}, - {0xc65, 0x801f801f}, - {0x855, 0x801fffff}, - {0xc66, 0x803f803f}, - {0x856, 0x803fffff}, - {0xc67, 0x807f807f}, - {0x857, 0x807fffff}, - {0xe70, 0x80808080}, - {0xc68, 0x80ff80ff}, - {0x858, 0x80ffffff}, - {0xe71, 0x81818181}, - {0xc69, 0x81ff81ff}, - {0x859, 0x81ffffff}, - {0xe72, 0x83838383}, - {0xc6a, 0x83ff83ff}, - {0x85a, 0x83ffffff}, - {0xe73, 0x87878787}, - {0xc6b, 0x87ff87ff}, - {0x85b, 0x87ffffff}, - {0xf78, 0x88888888}, - {0xe74, 0x8f8f8f8f}, - {0xc6c, 0x8fff8fff}, - {0x85c, 0x8fffffff}, - {0xf79, 0x99999999}, - {0xe75, 0x9f9f9f9f}, - {0xc6d, 0x9fff9fff}, - {0x85d, 0x9fffffff}, - {0xffc, 0xaaaaaaaa}, - {0xf7a, 0xbbbbbbbb}, - {0xe76, 0xbfbfbfbf}, - {0xc6e, 0xbfffbfff}, - {0x85e, 0xbfffffff}, - {0x881, 0xc0000000}, - {0x882, 0xc0000001}, - {0x883, 0xc0000003}, - {0x884, 0xc0000007}, - {0x885, 0xc000000f}, - {0x886, 0xc000001f}, - {0x887, 0xc000003f}, - {0x888, 0xc000007f}, - {0x889, 0xc00000ff}, - {0x88a, 0xc00001ff}, - {0x88b, 0xc00003ff}, - {0x88c, 0xc00007ff}, - {0x88d, 0xc0000fff}, - {0x88e, 0xc0001fff}, - {0x88f, 0xc0003fff}, - {0x890, 0xc0007fff}, - {0xca1, 0xc000c000}, - {0x891, 0xc000ffff}, - {0xca2, 0xc001c001}, - {0x892, 0xc001ffff}, - {0xca3, 0xc003c003}, - {0x893, 0xc003ffff}, - {0xca4, 0xc007c007}, - {0x894, 0xc007ffff}, - {0xca5, 0xc00fc00f}, - {0x895, 0xc00fffff}, - {0xca6, 0xc01fc01f}, - {0x896, 0xc01fffff}, - {0xca7, 0xc03fc03f}, - {0x897, 0xc03fffff}, - {0xca8, 0xc07fc07f}, - {0x898, 0xc07fffff}, - {0xeb1, 0xc0c0c0c0}, - {0xca9, 0xc0ffc0ff}, - {0x899, 0xc0ffffff}, - {0xeb2, 0xc1c1c1c1}, - {0xcaa, 0xc1ffc1ff}, - {0x89a, 0xc1ffffff}, - {0xeb3, 0xc3c3c3c3}, - {0xcab, 0xc3ffc3ff}, - {0x89b, 0xc3ffffff}, - {0xeb4, 0xc7c7c7c7}, - {0xcac, 0xc7ffc7ff}, - {0x89c, 0xc7ffffff}, - {0xfb9, 0xcccccccc}, - {0xeb5, 0xcfcfcfcf}, - {0xcad, 0xcfffcfff}, - {0x89d, 0xcfffffff}, - {0xfba, 0xdddddddd}, - {0xeb6, 0xdfdfdfdf}, - {0xcae, 0xdfffdfff}, - {0x89e, 0xdfffffff}, - {0x8c2, 0xe0000000}, - {0x8c3, 0xe0000001}, - {0x8c4, 0xe0000003}, - {0x8c5, 0xe0000007}, - {0x8c6, 0xe000000f}, - {0x8c7, 0xe000001f}, - {0x8c8, 0xe000003f}, - {0x8c9, 0xe000007f}, - {0x8ca, 0xe00000ff}, - {0x8cb, 0xe00001ff}, - {0x8cc, 0xe00003ff}, - {0x8cd, 0xe00007ff}, - {0x8ce, 0xe0000fff}, - {0x8cf, 0xe0001fff}, - {0x8d0, 0xe0003fff}, - {0x8d1, 0xe0007fff}, - {0xce2, 0xe000e000}, - {0x8d2, 0xe000ffff}, - {0xce3, 0xe001e001}, - {0x8d3, 0xe001ffff}, - {0xce4, 0xe003e003}, - {0x8d4, 0xe003ffff}, - {0xce5, 0xe007e007}, - {0x8d5, 0xe007ffff}, - {0xce6, 0xe00fe00f}, - {0x8d6, 0xe00fffff}, - {0xce7, 0xe01fe01f}, - {0x8d7, 0xe01fffff}, - {0xce8, 0xe03fe03f}, - {0x8d8, 0xe03fffff}, - {0xce9, 0xe07fe07f}, - {0x8d9, 0xe07fffff}, - {0xef2, 0xe0e0e0e0}, - {0xcea, 0xe0ffe0ff}, - {0x8da, 0xe0ffffff}, - {0xef3, 0xe1e1e1e1}, - {0xceb, 0xe1ffe1ff}, - {0x8db, 0xe1ffffff}, - {0xef4, 0xe3e3e3e3}, - {0xcec, 0xe3ffe3ff}, - {0x8dc, 0xe3ffffff}, - {0xef5, 0xe7e7e7e7}, - {0xced, 0xe7ffe7ff}, - {0x8dd, 0xe7ffffff}, - {0xffa, 0xeeeeeeee}, - {0xef6, 0xefefefef}, - {0xcee, 0xefffefff}, - {0x8de, 0xefffffff}, - {0x903, 0xf0000000}, - {0x904, 0xf0000001}, - {0x905, 0xf0000003}, - {0x906, 0xf0000007}, - {0x907, 0xf000000f}, - {0x908, 0xf000001f}, - {0x909, 0xf000003f}, - {0x90a, 0xf000007f}, - {0x90b, 0xf00000ff}, - {0x90c, 0xf00001ff}, - {0x90d, 0xf00003ff}, - {0x90e, 0xf00007ff}, - {0x90f, 0xf0000fff}, - {0x910, 0xf0001fff}, - {0x911, 0xf0003fff}, - {0x912, 0xf0007fff}, - {0xd23, 0xf000f000}, - {0x913, 0xf000ffff}, - {0xd24, 0xf001f001}, - {0x914, 0xf001ffff}, - {0xd25, 0xf003f003}, - {0x915, 0xf003ffff}, - {0xd26, 0xf007f007}, - {0x916, 0xf007ffff}, - {0xd27, 0xf00ff00f}, - {0x917, 0xf00fffff}, - {0xd28, 0xf01ff01f}, - {0x918, 0xf01fffff}, - {0xd29, 0xf03ff03f}, - {0x919, 0xf03fffff}, - {0xd2a, 0xf07ff07f}, - {0x91a, 0xf07fffff}, - {0xf33, 0xf0f0f0f0}, - {0xd2b, 0xf0fff0ff}, - {0x91b, 0xf0ffffff}, - {0xf34, 0xf1f1f1f1}, - {0xd2c, 0xf1fff1ff}, - {0x91c, 0xf1ffffff}, - {0xf35, 0xf3f3f3f3}, - {0xd2d, 0xf3fff3ff}, - {0x91d, 0xf3ffffff}, - {0xf36, 0xf7f7f7f7}, - {0xd2e, 0xf7fff7ff}, - {0x91e, 0xf7ffffff}, - {0x944, 0xf8000000}, - {0x945, 0xf8000001}, - {0x946, 0xf8000003}, - {0x947, 0xf8000007}, - {0x948, 0xf800000f}, - {0x949, 0xf800001f}, - {0x94a, 0xf800003f}, - {0x94b, 0xf800007f}, - {0x94c, 0xf80000ff}, - {0x94d, 0xf80001ff}, - {0x94e, 0xf80003ff}, - {0x94f, 0xf80007ff}, - {0x950, 0xf8000fff}, - {0x951, 0xf8001fff}, - {0x952, 0xf8003fff}, - {0x953, 0xf8007fff}, - {0xd64, 0xf800f800}, - {0x954, 0xf800ffff}, - {0xd65, 0xf801f801}, - {0x955, 0xf801ffff}, - {0xd66, 0xf803f803}, - {0x956, 0xf803ffff}, - {0xd67, 0xf807f807}, - {0x957, 0xf807ffff}, - {0xd68, 0xf80ff80f}, - {0x958, 0xf80fffff}, - {0xd69, 0xf81ff81f}, - {0x959, 0xf81fffff}, - {0xd6a, 0xf83ff83f}, - {0x95a, 0xf83fffff}, - {0xd6b, 0xf87ff87f}, - {0x95b, 0xf87fffff}, - {0xf74, 0xf8f8f8f8}, - {0xd6c, 0xf8fff8ff}, - {0x95c, 0xf8ffffff}, - {0xf75, 0xf9f9f9f9}, - {0xd6d, 0xf9fff9ff}, - {0x95d, 0xf9ffffff}, - {0xf76, 0xfbfbfbfb}, - {0xd6e, 0xfbfffbff}, - {0x95e, 0xfbffffff}, - {0x985, 0xfc000000}, - {0x986, 0xfc000001}, - {0x987, 0xfc000003}, - {0x988, 0xfc000007}, - {0x989, 0xfc00000f}, - {0x98a, 0xfc00001f}, - {0x98b, 0xfc00003f}, - {0x98c, 0xfc00007f}, - {0x98d, 0xfc0000ff}, - {0x98e, 0xfc0001ff}, - {0x98f, 0xfc0003ff}, - {0x990, 0xfc0007ff}, - {0x991, 0xfc000fff}, - {0x992, 0xfc001fff}, - {0x993, 0xfc003fff}, - {0x994, 0xfc007fff}, - {0xda5, 0xfc00fc00}, - {0x995, 0xfc00ffff}, - {0xda6, 0xfc01fc01}, - {0x996, 0xfc01ffff}, - {0xda7, 0xfc03fc03}, - {0x997, 0xfc03ffff}, - {0xda8, 0xfc07fc07}, - {0x998, 0xfc07ffff}, - {0xda9, 0xfc0ffc0f}, - {0x999, 0xfc0fffff}, - {0xdaa, 0xfc1ffc1f}, - {0x99a, 0xfc1fffff}, - {0xdab, 0xfc3ffc3f}, - {0x99b, 0xfc3fffff}, - {0xdac, 0xfc7ffc7f}, - {0x99c, 0xfc7fffff}, - {0xfb5, 0xfcfcfcfc}, - {0xdad, 0xfcfffcff}, - {0x99d, 0xfcffffff}, - {0xfb6, 0xfdfdfdfd}, - {0xdae, 0xfdfffdff}, - {0x99e, 0xfdffffff}, - {0x9c6, 0xfe000000}, - {0x9c7, 0xfe000001}, - {0x9c8, 0xfe000003}, - {0x9c9, 0xfe000007}, - {0x9ca, 0xfe00000f}, - {0x9cb, 0xfe00001f}, - {0x9cc, 0xfe00003f}, - {0x9cd, 0xfe00007f}, - {0x9ce, 0xfe0000ff}, - {0x9cf, 0xfe0001ff}, - {0x9d0, 0xfe0003ff}, - {0x9d1, 0xfe0007ff}, - {0x9d2, 0xfe000fff}, - {0x9d3, 0xfe001fff}, - {0x9d4, 0xfe003fff}, - {0x9d5, 0xfe007fff}, - {0xde6, 0xfe00fe00}, - {0x9d6, 0xfe00ffff}, - {0xde7, 0xfe01fe01}, - {0x9d7, 0xfe01ffff}, - {0xde8, 0xfe03fe03}, - {0x9d8, 0xfe03ffff}, - {0xde9, 0xfe07fe07}, - {0x9d9, 0xfe07ffff}, - {0xdea, 0xfe0ffe0f}, - {0x9da, 0xfe0fffff}, - {0xdeb, 0xfe1ffe1f}, - {0x9db, 0xfe1fffff}, - {0xdec, 0xfe3ffe3f}, - {0x9dc, 0xfe3fffff}, - {0xded, 0xfe7ffe7f}, - {0x9dd, 0xfe7fffff}, - {0xff6, 0xfefefefe}, - {0xdee, 0xfefffeff}, - {0x9de, 0xfeffffff}, - {0xa07, 0xff000000}, - {0xa08, 0xff000001}, - {0xa09, 0xff000003}, - {0xa0a, 0xff000007}, - {0xa0b, 0xff00000f}, - {0xa0c, 0xff00001f}, - {0xa0d, 0xff00003f}, - {0xa0e, 0xff00007f}, - {0xa0f, 0xff0000ff}, - {0xa10, 0xff0001ff}, - {0xa11, 0xff0003ff}, - {0xa12, 0xff0007ff}, - {0xa13, 0xff000fff}, - {0xa14, 0xff001fff}, - {0xa15, 0xff003fff}, - {0xa16, 0xff007fff}, - {0xe27, 0xff00ff00}, - {0xa17, 0xff00ffff}, - {0xe28, 0xff01ff01}, - {0xa18, 0xff01ffff}, - {0xe29, 0xff03ff03}, - {0xa19, 0xff03ffff}, - {0xe2a, 0xff07ff07}, - {0xa1a, 0xff07ffff}, - {0xe2b, 0xff0fff0f}, - {0xa1b, 0xff0fffff}, - {0xe2c, 0xff1fff1f}, - {0xa1c, 0xff1fffff}, - {0xe2d, 0xff3fff3f}, - {0xa1d, 0xff3fffff}, - {0xe2e, 0xff7fff7f}, - {0xa1e, 0xff7fffff}, - {0xa48, 0xff800000}, - {0xa49, 0xff800001}, - {0xa4a, 0xff800003}, - {0xa4b, 0xff800007}, - {0xa4c, 0xff80000f}, - {0xa4d, 0xff80001f}, - {0xa4e, 0xff80003f}, - {0xa4f, 0xff80007f}, - {0xa50, 0xff8000ff}, - {0xa51, 0xff8001ff}, - {0xa52, 0xff8003ff}, - {0xa53, 0xff8007ff}, - {0xa54, 0xff800fff}, - {0xa55, 0xff801fff}, - {0xa56, 0xff803fff}, - {0xa57, 0xff807fff}, - {0xe68, 0xff80ff80}, - {0xa58, 0xff80ffff}, - {0xe69, 0xff81ff81}, - {0xa59, 0xff81ffff}, - {0xe6a, 0xff83ff83}, - {0xa5a, 0xff83ffff}, - {0xe6b, 0xff87ff87}, - {0xa5b, 0xff87ffff}, - {0xe6c, 0xff8fff8f}, - {0xa5c, 0xff8fffff}, - {0xe6d, 0xff9fff9f}, - {0xa5d, 0xff9fffff}, - {0xe6e, 0xffbfffbf}, - {0xa5e, 0xffbfffff}, - {0xa89, 0xffc00000}, - {0xa8a, 0xffc00001}, - {0xa8b, 0xffc00003}, - {0xa8c, 0xffc00007}, - {0xa8d, 0xffc0000f}, - {0xa8e, 0xffc0001f}, - {0xa8f, 0xffc0003f}, - {0xa90, 0xffc0007f}, - {0xa91, 0xffc000ff}, - {0xa92, 0xffc001ff}, - {0xa93, 0xffc003ff}, - {0xa94, 0xffc007ff}, - {0xa95, 0xffc00fff}, - {0xa96, 0xffc01fff}, - {0xa97, 0xffc03fff}, - {0xa98, 0xffc07fff}, - {0xea9, 0xffc0ffc0}, - {0xa99, 0xffc0ffff}, - {0xeaa, 0xffc1ffc1}, - {0xa9a, 0xffc1ffff}, - {0xeab, 0xffc3ffc3}, - {0xa9b, 0xffc3ffff}, - {0xeac, 0xffc7ffc7}, - {0xa9c, 0xffc7ffff}, - {0xead, 0xffcfffcf}, - {0xa9d, 0xffcfffff}, - {0xeae, 0xffdfffdf}, - {0xa9e, 0xffdfffff}, - {0xaca, 0xffe00000}, - {0xacb, 0xffe00001}, - {0xacc, 0xffe00003}, - {0xacd, 0xffe00007}, - {0xace, 0xffe0000f}, - {0xacf, 0xffe0001f}, - {0xad0, 0xffe0003f}, - {0xad1, 0xffe0007f}, - {0xad2, 0xffe000ff}, - {0xad3, 0xffe001ff}, - {0xad4, 0xffe003ff}, - {0xad5, 0xffe007ff}, - {0xad6, 0xffe00fff}, - {0xad7, 0xffe01fff}, - {0xad8, 0xffe03fff}, - {0xad9, 0xffe07fff}, - {0xeea, 0xffe0ffe0}, - {0xada, 0xffe0ffff}, - {0xeeb, 0xffe1ffe1}, - {0xadb, 0xffe1ffff}, - {0xeec, 0xffe3ffe3}, - {0xadc, 0xffe3ffff}, - {0xeed, 0xffe7ffe7}, - {0xadd, 0xffe7ffff}, - {0xeee, 0xffefffef}, - {0xade, 0xffefffff}, - {0xb0b, 0xfff00000}, - {0xb0c, 0xfff00001}, - {0xb0d, 0xfff00003}, - {0xb0e, 0xfff00007}, - {0xb0f, 0xfff0000f}, - {0xb10, 0xfff0001f}, - {0xb11, 0xfff0003f}, - {0xb12, 0xfff0007f}, - {0xb13, 0xfff000ff}, - {0xb14, 0xfff001ff}, - {0xb15, 0xfff003ff}, - {0xb16, 0xfff007ff}, - {0xb17, 0xfff00fff}, - {0xb18, 0xfff01fff}, - {0xb19, 0xfff03fff}, - {0xb1a, 0xfff07fff}, - {0xf2b, 0xfff0fff0}, - {0xb1b, 0xfff0ffff}, - {0xf2c, 0xfff1fff1}, - {0xb1c, 0xfff1ffff}, - {0xf2d, 0xfff3fff3}, - {0xb1d, 0xfff3ffff}, - {0xf2e, 0xfff7fff7}, - {0xb1e, 0xfff7ffff}, - {0xb4c, 0xfff80000}, - {0xb4d, 0xfff80001}, - {0xb4e, 0xfff80003}, - {0xb4f, 0xfff80007}, - {0xb50, 0xfff8000f}, - {0xb51, 0xfff8001f}, - {0xb52, 0xfff8003f}, - {0xb53, 0xfff8007f}, - {0xb54, 0xfff800ff}, - {0xb55, 0xfff801ff}, - {0xb56, 0xfff803ff}, - {0xb57, 0xfff807ff}, - {0xb58, 0xfff80fff}, - {0xb59, 0xfff81fff}, - {0xb5a, 0xfff83fff}, - {0xb5b, 0xfff87fff}, - {0xf6c, 0xfff8fff8}, - {0xb5c, 0xfff8ffff}, - {0xf6d, 0xfff9fff9}, - {0xb5d, 0xfff9ffff}, - {0xf6e, 0xfffbfffb}, - {0xb5e, 0xfffbffff}, - {0xb8d, 0xfffc0000}, - {0xb8e, 0xfffc0001}, - {0xb8f, 0xfffc0003}, - {0xb90, 0xfffc0007}, - {0xb91, 0xfffc000f}, - {0xb92, 0xfffc001f}, - {0xb93, 0xfffc003f}, - {0xb94, 0xfffc007f}, - {0xb95, 0xfffc00ff}, - {0xb96, 0xfffc01ff}, - {0xb97, 0xfffc03ff}, - {0xb98, 0xfffc07ff}, - {0xb99, 0xfffc0fff}, - {0xb9a, 0xfffc1fff}, - {0xb9b, 0xfffc3fff}, - {0xb9c, 0xfffc7fff}, - {0xfad, 0xfffcfffc}, - {0xb9d, 0xfffcffff}, - {0xfae, 0xfffdfffd}, - {0xb9e, 0xfffdffff}, - {0xbce, 0xfffe0000}, - {0xbcf, 0xfffe0001}, - {0xbd0, 0xfffe0003}, - {0xbd1, 0xfffe0007}, - {0xbd2, 0xfffe000f}, - {0xbd3, 0xfffe001f}, - {0xbd4, 0xfffe003f}, - {0xbd5, 0xfffe007f}, - {0xbd6, 0xfffe00ff}, - {0xbd7, 0xfffe01ff}, - {0xbd8, 0xfffe03ff}, - {0xbd9, 0xfffe07ff}, - {0xbda, 0xfffe0fff}, - {0xbdb, 0xfffe1fff}, - {0xbdc, 0xfffe3fff}, - {0xbdd, 0xfffe7fff}, - {0xfee, 0xfffefffe}, - {0xbde, 0xfffeffff}, - {0xc0f, 0xffff0000}, - {0xc10, 0xffff0001}, - {0xc11, 0xffff0003}, - {0xc12, 0xffff0007}, - {0xc13, 0xffff000f}, - {0xc14, 0xffff001f}, - {0xc15, 0xffff003f}, - {0xc16, 0xffff007f}, - {0xc17, 0xffff00ff}, - {0xc18, 0xffff01ff}, - {0xc19, 0xffff03ff}, - {0xc1a, 0xffff07ff}, - {0xc1b, 0xffff0fff}, - {0xc1c, 0xffff1fff}, - {0xc1d, 0xffff3fff}, - {0xc1e, 0xffff7fff}, - {0xc50, 0xffff8000}, - {0xc51, 0xffff8001}, - {0xc52, 0xffff8003}, - {0xc53, 0xffff8007}, - {0xc54, 0xffff800f}, - {0xc55, 0xffff801f}, - {0xc56, 0xffff803f}, - {0xc57, 0xffff807f}, - {0xc58, 0xffff80ff}, - {0xc59, 0xffff81ff}, - {0xc5a, 0xffff83ff}, - {0xc5b, 0xffff87ff}, - {0xc5c, 0xffff8fff}, - {0xc5d, 0xffff9fff}, - {0xc5e, 0xffffbfff}, - {0xc91, 0xffffc000}, - {0xc92, 0xffffc001}, - {0xc93, 0xffffc003}, - {0xc94, 0xffffc007}, - {0xc95, 0xffffc00f}, - {0xc96, 0xffffc01f}, - {0xc97, 0xffffc03f}, - {0xc98, 0xffffc07f}, - {0xc99, 0xffffc0ff}, - {0xc9a, 0xffffc1ff}, - {0xc9b, 0xffffc3ff}, - {0xc9c, 0xffffc7ff}, - {0xc9d, 0xffffcfff}, - {0xc9e, 0xffffdfff}, - {0xcd2, 0xffffe000}, - {0xcd3, 0xffffe001}, - {0xcd4, 0xffffe003}, - {0xcd5, 0xffffe007}, - {0xcd6, 0xffffe00f}, - {0xcd7, 0xffffe01f}, - {0xcd8, 0xffffe03f}, - {0xcd9, 0xffffe07f}, - {0xcda, 0xffffe0ff}, - {0xcdb, 0xffffe1ff}, - {0xcdc, 0xffffe3ff}, - {0xcdd, 0xffffe7ff}, - {0xcde, 0xffffefff}, - {0xd13, 0xfffff000}, - {0xd14, 0xfffff001}, - {0xd15, 0xfffff003}, - {0xd16, 0xfffff007}, - {0xd17, 0xfffff00f}, - {0xd18, 0xfffff01f}, - {0xd19, 0xfffff03f}, - {0xd1a, 0xfffff07f}, - {0xd1b, 0xfffff0ff}, - {0xd1c, 0xfffff1ff}, - {0xd1d, 0xfffff3ff}, - {0xd1e, 0xfffff7ff}, - {0xd54, 0xfffff800}, - {0xd55, 0xfffff801}, - {0xd56, 0xfffff803}, - {0xd57, 0xfffff807}, - {0xd58, 0xfffff80f}, - {0xd59, 0xfffff81f}, - {0xd5a, 0xfffff83f}, - {0xd5b, 0xfffff87f}, - {0xd5c, 0xfffff8ff}, - {0xd5d, 0xfffff9ff}, - {0xd5e, 0xfffffbff}, - {0xd95, 0xfffffc00}, - {0xd96, 0xfffffc01}, - {0xd97, 0xfffffc03}, - {0xd98, 0xfffffc07}, - {0xd99, 0xfffffc0f}, - {0xd9a, 0xfffffc1f}, - {0xd9b, 0xfffffc3f}, - {0xd9c, 0xfffffc7f}, - {0xd9d, 0xfffffcff}, - {0xd9e, 0xfffffdff}, - {0xdd6, 0xfffffe00}, - {0xdd7, 0xfffffe01}, - {0xdd8, 0xfffffe03}, - {0xdd9, 0xfffffe07}, - {0xdda, 0xfffffe0f}, - {0xddb, 0xfffffe1f}, - {0xddc, 0xfffffe3f}, - {0xddd, 0xfffffe7f}, - {0xdde, 0xfffffeff}, - {0xe17, 0xffffff00}, - {0xe18, 0xffffff01}, - {0xe19, 0xffffff03}, - {0xe1a, 0xffffff07}, - {0xe1b, 0xffffff0f}, - {0xe1c, 0xffffff1f}, - {0xe1d, 0xffffff3f}, - {0xe1e, 0xffffff7f}, - {0xe58, 0xffffff80}, - {0xe59, 0xffffff81}, - {0xe5a, 0xffffff83}, - {0xe5b, 0xffffff87}, - {0xe5c, 0xffffff8f}, - {0xe5d, 0xffffff9f}, - {0xe5e, 0xffffffbf}, - {0xe99, 0xffffffc0}, - {0xe9a, 0xffffffc1}, - {0xe9b, 0xffffffc3}, - {0xe9c, 0xffffffc7}, - {0xe9d, 0xffffffcf}, - {0xe9e, 0xffffffdf}, - {0xeda, 0xffffffe0}, - {0xedb, 0xffffffe1}, - {0xedc, 0xffffffe3}, - {0xedd, 0xffffffe7}, - {0xede, 0xffffffef}, - {0xf1b, 0xfffffff0}, - {0xf1c, 0xfffffff1}, - {0xf1d, 0xfffffff3}, - {0xf1e, 0xfffffff7}, - {0xf5c, 0xfffffff8}, - {0xf5d, 0xfffffff9}, - {0xf5e, 0xfffffffb}, - {0xf9d, 0xfffffffc}, - {0xf9e, 0xfffffffd}, - {0xfde, 0xfffffffe}, +static uint32_t imm_table[][2] = { + {0x800, 0x00000001}, + { 0xfc0, 0x00000002}, + { 0x801, 0x00000003}, + { 0xf80, 0x00000004}, + { 0xfc1, 0x00000006}, + { 0x802, 0x00000007}, + { 0xf40, 0x00000008}, + { 0xf81, 0x0000000c}, + { 0xfc2, 0x0000000e}, + { 0x803, 0x0000000f}, + { 0xf00, 0x00000010}, + { 0xf41, 0x00000018}, + { 0xf82, 0x0000001c}, + { 0xfc3, 0x0000001e}, + { 0x804, 0x0000001f}, + { 0xec0, 0x00000020}, + { 0xf01, 0x00000030}, + { 0xf42, 0x00000038}, + { 0xf83, 0x0000003c}, + { 0xfc4, 0x0000003e}, + { 0x805, 0x0000003f}, + { 0xe80, 0x00000040}, + { 0xec1, 0x00000060}, + { 0xf02, 0x00000070}, + { 0xf43, 0x00000078}, + { 0xf84, 0x0000007c}, + { 0xfc5, 0x0000007e}, + { 0x806, 0x0000007f}, + { 0xe40, 0x00000080}, + { 0xe81, 0x000000c0}, + { 0xec2, 0x000000e0}, + { 0xf03, 0x000000f0}, + { 0xf44, 0x000000f8}, + { 0xf85, 0x000000fc}, + { 0xfc6, 0x000000fe}, + { 0x807, 0x000000ff}, + { 0xe00, 0x00000100}, + { 0xe41, 0x00000180}, + { 0xe82, 0x000001c0}, + { 0xec3, 0x000001e0}, + { 0xf04, 0x000001f0}, + { 0xf45, 0x000001f8}, + { 0xf86, 0x000001fc}, + { 0xfc7, 0x000001fe}, + { 0x808, 0x000001ff}, + { 0xdc0, 0x00000200}, + { 0xe01, 0x00000300}, + { 0xe42, 0x00000380}, + { 0xe83, 0x000003c0}, + { 0xec4, 0x000003e0}, + { 0xf05, 0x000003f0}, + { 0xf46, 0x000003f8}, + { 0xf87, 0x000003fc}, + { 0xfc8, 0x000003fe}, + { 0x809, 0x000003ff}, + { 0xd80, 0x00000400}, + { 0xdc1, 0x00000600}, + { 0xe02, 0x00000700}, + { 0xe43, 0x00000780}, + { 0xe84, 0x000007c0}, + { 0xec5, 0x000007e0}, + { 0xf06, 0x000007f0}, + { 0xf47, 0x000007f8}, + { 0xf88, 0x000007fc}, + { 0xfc9, 0x000007fe}, + { 0x80a, 0x000007ff}, + { 0xd40, 0x00000800}, + { 0xd81, 0x00000c00}, + { 0xdc2, 0x00000e00}, + { 0xe03, 0x00000f00}, + { 0xe44, 0x00000f80}, + { 0xe85, 0x00000fc0}, + { 0xec6, 0x00000fe0}, + { 0xf07, 0x00000ff0}, + { 0xf48, 0x00000ff8}, + { 0xf89, 0x00000ffc}, + { 0xfca, 0x00000ffe}, + { 0x80b, 0x00000fff}, + { 0xd00, 0x00001000}, + { 0xd41, 0x00001800}, + { 0xd82, 0x00001c00}, + { 0xdc3, 0x00001e00}, + { 0xe04, 0x00001f00}, + { 0xe45, 0x00001f80}, + { 0xe86, 0x00001fc0}, + { 0xec7, 0x00001fe0}, + { 0xf08, 0x00001ff0}, + { 0xf49, 0x00001ff8}, + { 0xf8a, 0x00001ffc}, + { 0xfcb, 0x00001ffe}, + { 0x80c, 0x00001fff}, + { 0xcc0, 0x00002000}, + { 0xd01, 0x00003000}, + { 0xd42, 0x00003800}, + { 0xd83, 0x00003c00}, + { 0xdc4, 0x00003e00}, + { 0xe05, 0x00003f00}, + { 0xe46, 0x00003f80}, + { 0xe87, 0x00003fc0}, + { 0xec8, 0x00003fe0}, + { 0xf09, 0x00003ff0}, + { 0xf4a, 0x00003ff8}, + { 0xf8b, 0x00003ffc}, + { 0xfcc, 0x00003ffe}, + { 0x80d, 0x00003fff}, + { 0xc80, 0x00004000}, + { 0xcc1, 0x00006000}, + { 0xd02, 0x00007000}, + { 0xd43, 0x00007800}, + { 0xd84, 0x00007c00}, + { 0xdc5, 0x00007e00}, + { 0xe06, 0x00007f00}, + { 0xe47, 0x00007f80}, + { 0xe88, 0x00007fc0}, + { 0xec9, 0x00007fe0}, + { 0xf0a, 0x00007ff0}, + { 0xf4b, 0x00007ff8}, + { 0xf8c, 0x00007ffc}, + { 0xfcd, 0x00007ffe}, + { 0x80e, 0x00007fff}, + { 0xc40, 0x00008000}, + { 0xc81, 0x0000c000}, + { 0xcc2, 0x0000e000}, + { 0xd03, 0x0000f000}, + { 0xd44, 0x0000f800}, + { 0xd85, 0x0000fc00}, + { 0xdc6, 0x0000fe00}, + { 0xe07, 0x0000ff00}, + { 0xe48, 0x0000ff80}, + { 0xe89, 0x0000ffc0}, + { 0xeca, 0x0000ffe0}, + { 0xf0b, 0x0000fff0}, + { 0xf4c, 0x0000fff8}, + { 0xf8d, 0x0000fffc}, + { 0xfce, 0x0000fffe}, + { 0x80f, 0x0000ffff}, + { 0xc00, 0x00010000}, + { 0xc20, 0x00010001}, + { 0xc41, 0x00018000}, + { 0xc82, 0x0001c000}, + { 0xcc3, 0x0001e000}, + { 0xd04, 0x0001f000}, + { 0xd45, 0x0001f800}, + { 0xd86, 0x0001fc00}, + { 0xdc7, 0x0001fe00}, + { 0xe08, 0x0001ff00}, + { 0xe49, 0x0001ff80}, + { 0xe8a, 0x0001ffc0}, + { 0xecb, 0x0001ffe0}, + { 0xf0c, 0x0001fff0}, + { 0xf4d, 0x0001fff8}, + { 0xf8e, 0x0001fffc}, + { 0xfcf, 0x0001fffe}, + { 0x810, 0x0001ffff}, + { 0xbc0, 0x00020000}, + { 0xfe0, 0x00020002}, + { 0xc01, 0x00030000}, + { 0xc21, 0x00030003}, + { 0xc42, 0x00038000}, + { 0xc83, 0x0003c000}, + { 0xcc4, 0x0003e000}, + { 0xd05, 0x0003f000}, + { 0xd46, 0x0003f800}, + { 0xd87, 0x0003fc00}, + { 0xdc8, 0x0003fe00}, + { 0xe09, 0x0003ff00}, + { 0xe4a, 0x0003ff80}, + { 0xe8b, 0x0003ffc0}, + { 0xecc, 0x0003ffe0}, + { 0xf0d, 0x0003fff0}, + { 0xf4e, 0x0003fff8}, + { 0xf8f, 0x0003fffc}, + { 0xfd0, 0x0003fffe}, + { 0x811, 0x0003ffff}, + { 0xb80, 0x00040000}, + { 0xfa0, 0x00040004}, + { 0xbc1, 0x00060000}, + { 0xfe1, 0x00060006}, + { 0xc02, 0x00070000}, + { 0xc22, 0x00070007}, + { 0xc43, 0x00078000}, + { 0xc84, 0x0007c000}, + { 0xcc5, 0x0007e000}, + { 0xd06, 0x0007f000}, + { 0xd47, 0x0007f800}, + { 0xd88, 0x0007fc00}, + { 0xdc9, 0x0007fe00}, + { 0xe0a, 0x0007ff00}, + { 0xe4b, 0x0007ff80}, + { 0xe8c, 0x0007ffc0}, + { 0xecd, 0x0007ffe0}, + { 0xf0e, 0x0007fff0}, + { 0xf4f, 0x0007fff8}, + { 0xf90, 0x0007fffc}, + { 0xfd1, 0x0007fffe}, + { 0x812, 0x0007ffff}, + { 0xb40, 0x00080000}, + { 0xf60, 0x00080008}, + { 0xb81, 0x000c0000}, + { 0xfa1, 0x000c000c}, + { 0xbc2, 0x000e0000}, + { 0xfe2, 0x000e000e}, + { 0xc03, 0x000f0000}, + { 0xc23, 0x000f000f}, + { 0xc44, 0x000f8000}, + { 0xc85, 0x000fc000}, + { 0xcc6, 0x000fe000}, + { 0xd07, 0x000ff000}, + { 0xd48, 0x000ff800}, + { 0xd89, 0x000ffc00}, + { 0xdca, 0x000ffe00}, + { 0xe0b, 0x000fff00}, + { 0xe4c, 0x000fff80}, + { 0xe8d, 0x000fffc0}, + { 0xece, 0x000fffe0}, + { 0xf0f, 0x000ffff0}, + { 0xf50, 0x000ffff8}, + { 0xf91, 0x000ffffc}, + { 0xfd2, 0x000ffffe}, + { 0x813, 0x000fffff}, + { 0xb00, 0x00100000}, + { 0xf20, 0x00100010}, + { 0xb41, 0x00180000}, + { 0xf61, 0x00180018}, + { 0xb82, 0x001c0000}, + { 0xfa2, 0x001c001c}, + { 0xbc3, 0x001e0000}, + { 0xfe3, 0x001e001e}, + { 0xc04, 0x001f0000}, + { 0xc24, 0x001f001f}, + { 0xc45, 0x001f8000}, + { 0xc86, 0x001fc000}, + { 0xcc7, 0x001fe000}, + { 0xd08, 0x001ff000}, + { 0xd49, 0x001ff800}, + { 0xd8a, 0x001ffc00}, + { 0xdcb, 0x001ffe00}, + { 0xe0c, 0x001fff00}, + { 0xe4d, 0x001fff80}, + { 0xe8e, 0x001fffc0}, + { 0xecf, 0x001fffe0}, + { 0xf10, 0x001ffff0}, + { 0xf51, 0x001ffff8}, + { 0xf92, 0x001ffffc}, + { 0xfd3, 0x001ffffe}, + { 0x814, 0x001fffff}, + { 0xac0, 0x00200000}, + { 0xee0, 0x00200020}, + { 0xb01, 0x00300000}, + { 0xf21, 0x00300030}, + { 0xb42, 0x00380000}, + { 0xf62, 0x00380038}, + { 0xb83, 0x003c0000}, + { 0xfa3, 0x003c003c}, + { 0xbc4, 0x003e0000}, + { 0xfe4, 0x003e003e}, + { 0xc05, 0x003f0000}, + { 0xc25, 0x003f003f}, + { 0xc46, 0x003f8000}, + { 0xc87, 0x003fc000}, + { 0xcc8, 0x003fe000}, + { 0xd09, 0x003ff000}, + { 0xd4a, 0x003ff800}, + { 0xd8b, 0x003ffc00}, + { 0xdcc, 0x003ffe00}, + { 0xe0d, 0x003fff00}, + { 0xe4e, 0x003fff80}, + { 0xe8f, 0x003fffc0}, + { 0xed0, 0x003fffe0}, + { 0xf11, 0x003ffff0}, + { 0xf52, 0x003ffff8}, + { 0xf93, 0x003ffffc}, + { 0xfd4, 0x003ffffe}, + { 0x815, 0x003fffff}, + { 0xa80, 0x00400000}, + { 0xea0, 0x00400040}, + { 0xac1, 0x00600000}, + { 0xee1, 0x00600060}, + { 0xb02, 0x00700000}, + { 0xf22, 0x00700070}, + { 0xb43, 0x00780000}, + { 0xf63, 0x00780078}, + { 0xb84, 0x007c0000}, + { 0xfa4, 0x007c007c}, + { 0xbc5, 0x007e0000}, + { 0xfe5, 0x007e007e}, + { 0xc06, 0x007f0000}, + { 0xc26, 0x007f007f}, + { 0xc47, 0x007f8000}, + { 0xc88, 0x007fc000}, + { 0xcc9, 0x007fe000}, + { 0xd0a, 0x007ff000}, + { 0xd4b, 0x007ff800}, + { 0xd8c, 0x007ffc00}, + { 0xdcd, 0x007ffe00}, + { 0xe0e, 0x007fff00}, + { 0xe4f, 0x007fff80}, + { 0xe90, 0x007fffc0}, + { 0xed1, 0x007fffe0}, + { 0xf12, 0x007ffff0}, + { 0xf53, 0x007ffff8}, + { 0xf94, 0x007ffffc}, + { 0xfd5, 0x007ffffe}, + { 0x816, 0x007fffff}, + { 0xa40, 0x00800000}, + { 0xe60, 0x00800080}, + { 0xa81, 0x00c00000}, + { 0xea1, 0x00c000c0}, + { 0xac2, 0x00e00000}, + { 0xee2, 0x00e000e0}, + { 0xb03, 0x00f00000}, + { 0xf23, 0x00f000f0}, + { 0xb44, 0x00f80000}, + { 0xf64, 0x00f800f8}, + { 0xb85, 0x00fc0000}, + { 0xfa5, 0x00fc00fc}, + { 0xbc6, 0x00fe0000}, + { 0xfe6, 0x00fe00fe}, + { 0xc07, 0x00ff0000}, + { 0xc27, 0x00ff00ff}, + { 0xc48, 0x00ff8000}, + { 0xc89, 0x00ffc000}, + { 0xcca, 0x00ffe000}, + { 0xd0b, 0x00fff000}, + { 0xd4c, 0x00fff800}, + { 0xd8d, 0x00fffc00}, + { 0xdce, 0x00fffe00}, + { 0xe0f, 0x00ffff00}, + { 0xe50, 0x00ffff80}, + { 0xe91, 0x00ffffc0}, + { 0xed2, 0x00ffffe0}, + { 0xf13, 0x00fffff0}, + { 0xf54, 0x00fffff8}, + { 0xf95, 0x00fffffc}, + { 0xfd6, 0x00fffffe}, + { 0x817, 0x00ffffff}, + { 0xa00, 0x01000000}, + { 0xe20, 0x01000100}, + { 0xe30, 0x01010101}, + { 0xa41, 0x01800000}, + { 0xe61, 0x01800180}, + { 0xa82, 0x01c00000}, + { 0xea2, 0x01c001c0}, + { 0xac3, 0x01e00000}, + { 0xee3, 0x01e001e0}, + { 0xb04, 0x01f00000}, + { 0xf24, 0x01f001f0}, + { 0xb45, 0x01f80000}, + { 0xf65, 0x01f801f8}, + { 0xb86, 0x01fc0000}, + { 0xfa6, 0x01fc01fc}, + { 0xbc7, 0x01fe0000}, + { 0xfe7, 0x01fe01fe}, + { 0xc08, 0x01ff0000}, + { 0xc28, 0x01ff01ff}, + { 0xc49, 0x01ff8000}, + { 0xc8a, 0x01ffc000}, + { 0xccb, 0x01ffe000}, + { 0xd0c, 0x01fff000}, + { 0xd4d, 0x01fff800}, + { 0xd8e, 0x01fffc00}, + { 0xdcf, 0x01fffe00}, + { 0xe10, 0x01ffff00}, + { 0xe51, 0x01ffff80}, + { 0xe92, 0x01ffffc0}, + { 0xed3, 0x01ffffe0}, + { 0xf14, 0x01fffff0}, + { 0xf55, 0x01fffff8}, + { 0xf96, 0x01fffffc}, + { 0xfd7, 0x01fffffe}, + { 0x818, 0x01ffffff}, + { 0x9c0, 0x02000000}, + { 0xde0, 0x02000200}, + { 0xff0, 0x02020202}, + { 0xa01, 0x03000000}, + { 0xe21, 0x03000300}, + { 0xe31, 0x03030303}, + { 0xa42, 0x03800000}, + { 0xe62, 0x03800380}, + { 0xa83, 0x03c00000}, + { 0xea3, 0x03c003c0}, + { 0xac4, 0x03e00000}, + { 0xee4, 0x03e003e0}, + { 0xb05, 0x03f00000}, + { 0xf25, 0x03f003f0}, + { 0xb46, 0x03f80000}, + { 0xf66, 0x03f803f8}, + { 0xb87, 0x03fc0000}, + { 0xfa7, 0x03fc03fc}, + { 0xbc8, 0x03fe0000}, + { 0xfe8, 0x03fe03fe}, + { 0xc09, 0x03ff0000}, + { 0xc29, 0x03ff03ff}, + { 0xc4a, 0x03ff8000}, + { 0xc8b, 0x03ffc000}, + { 0xccc, 0x03ffe000}, + { 0xd0d, 0x03fff000}, + { 0xd4e, 0x03fff800}, + { 0xd8f, 0x03fffc00}, + { 0xdd0, 0x03fffe00}, + { 0xe11, 0x03ffff00}, + { 0xe52, 0x03ffff80}, + { 0xe93, 0x03ffffc0}, + { 0xed4, 0x03ffffe0}, + { 0xf15, 0x03fffff0}, + { 0xf56, 0x03fffff8}, + { 0xf97, 0x03fffffc}, + { 0xfd8, 0x03fffffe}, + { 0x819, 0x03ffffff}, + { 0x980, 0x04000000}, + { 0xda0, 0x04000400}, + { 0xfb0, 0x04040404}, + { 0x9c1, 0x06000000}, + { 0xde1, 0x06000600}, + { 0xff1, 0x06060606}, + { 0xa02, 0x07000000}, + { 0xe22, 0x07000700}, + { 0xe32, 0x07070707}, + { 0xa43, 0x07800000}, + { 0xe63, 0x07800780}, + { 0xa84, 0x07c00000}, + { 0xea4, 0x07c007c0}, + { 0xac5, 0x07e00000}, + { 0xee5, 0x07e007e0}, + { 0xb06, 0x07f00000}, + { 0xf26, 0x07f007f0}, + { 0xb47, 0x07f80000}, + { 0xf67, 0x07f807f8}, + { 0xb88, 0x07fc0000}, + { 0xfa8, 0x07fc07fc}, + { 0xbc9, 0x07fe0000}, + { 0xfe9, 0x07fe07fe}, + { 0xc0a, 0x07ff0000}, + { 0xc2a, 0x07ff07ff}, + { 0xc4b, 0x07ff8000}, + { 0xc8c, 0x07ffc000}, + { 0xccd, 0x07ffe000}, + { 0xd0e, 0x07fff000}, + { 0xd4f, 0x07fff800}, + { 0xd90, 0x07fffc00}, + { 0xdd1, 0x07fffe00}, + { 0xe12, 0x07ffff00}, + { 0xe53, 0x07ffff80}, + { 0xe94, 0x07ffffc0}, + { 0xed5, 0x07ffffe0}, + { 0xf16, 0x07fffff0}, + { 0xf57, 0x07fffff8}, + { 0xf98, 0x07fffffc}, + { 0xfd9, 0x07fffffe}, + { 0x81a, 0x07ffffff}, + { 0x940, 0x08000000}, + { 0xd60, 0x08000800}, + { 0xf70, 0x08080808}, + { 0x981, 0x0c000000}, + { 0xda1, 0x0c000c00}, + { 0xfb1, 0x0c0c0c0c}, + { 0x9c2, 0x0e000000}, + { 0xde2, 0x0e000e00}, + { 0xff2, 0x0e0e0e0e}, + { 0xa03, 0x0f000000}, + { 0xe23, 0x0f000f00}, + { 0xe33, 0x0f0f0f0f}, + { 0xa44, 0x0f800000}, + { 0xe64, 0x0f800f80}, + { 0xa85, 0x0fc00000}, + { 0xea5, 0x0fc00fc0}, + { 0xac6, 0x0fe00000}, + { 0xee6, 0x0fe00fe0}, + { 0xb07, 0x0ff00000}, + { 0xf27, 0x0ff00ff0}, + { 0xb48, 0x0ff80000}, + { 0xf68, 0x0ff80ff8}, + { 0xb89, 0x0ffc0000}, + { 0xfa9, 0x0ffc0ffc}, + { 0xbca, 0x0ffe0000}, + { 0xfea, 0x0ffe0ffe}, + { 0xc0b, 0x0fff0000}, + { 0xc2b, 0x0fff0fff}, + { 0xc4c, 0x0fff8000}, + { 0xc8d, 0x0fffc000}, + { 0xcce, 0x0fffe000}, + { 0xd0f, 0x0ffff000}, + { 0xd50, 0x0ffff800}, + { 0xd91, 0x0ffffc00}, + { 0xdd2, 0x0ffffe00}, + { 0xe13, 0x0fffff00}, + { 0xe54, 0x0fffff80}, + { 0xe95, 0x0fffffc0}, + { 0xed6, 0x0fffffe0}, + { 0xf17, 0x0ffffff0}, + { 0xf58, 0x0ffffff8}, + { 0xf99, 0x0ffffffc}, + { 0xfda, 0x0ffffffe}, + { 0x81b, 0x0fffffff}, + { 0x900, 0x10000000}, + { 0xd20, 0x10001000}, + { 0xf30, 0x10101010}, + { 0xf38, 0x11111111}, + { 0x941, 0x18000000}, + { 0xd61, 0x18001800}, + { 0xf71, 0x18181818}, + { 0x982, 0x1c000000}, + { 0xda2, 0x1c001c00}, + { 0xfb2, 0x1c1c1c1c}, + { 0x9c3, 0x1e000000}, + { 0xde3, 0x1e001e00}, + { 0xff3, 0x1e1e1e1e}, + { 0xa04, 0x1f000000}, + { 0xe24, 0x1f001f00}, + { 0xe34, 0x1f1f1f1f}, + { 0xa45, 0x1f800000}, + { 0xe65, 0x1f801f80}, + { 0xa86, 0x1fc00000}, + { 0xea6, 0x1fc01fc0}, + { 0xac7, 0x1fe00000}, + { 0xee7, 0x1fe01fe0}, + { 0xb08, 0x1ff00000}, + { 0xf28, 0x1ff01ff0}, + { 0xb49, 0x1ff80000}, + { 0xf69, 0x1ff81ff8}, + { 0xb8a, 0x1ffc0000}, + { 0xfaa, 0x1ffc1ffc}, + { 0xbcb, 0x1ffe0000}, + { 0xfeb, 0x1ffe1ffe}, + { 0xc0c, 0x1fff0000}, + { 0xc2c, 0x1fff1fff}, + { 0xc4d, 0x1fff8000}, + { 0xc8e, 0x1fffc000}, + { 0xccf, 0x1fffe000}, + { 0xd10, 0x1ffff000}, + { 0xd51, 0x1ffff800}, + { 0xd92, 0x1ffffc00}, + { 0xdd3, 0x1ffffe00}, + { 0xe14, 0x1fffff00}, + { 0xe55, 0x1fffff80}, + { 0xe96, 0x1fffffc0}, + { 0xed7, 0x1fffffe0}, + { 0xf18, 0x1ffffff0}, + { 0xf59, 0x1ffffff8}, + { 0xf9a, 0x1ffffffc}, + { 0xfdb, 0x1ffffffe}, + { 0x81c, 0x1fffffff}, + { 0x8c0, 0x20000000}, + { 0xce0, 0x20002000}, + { 0xef0, 0x20202020}, + { 0xff8, 0x22222222}, + { 0x901, 0x30000000}, + { 0xd21, 0x30003000}, + { 0xf31, 0x30303030}, + { 0xf39, 0x33333333}, + { 0x942, 0x38000000}, + { 0xd62, 0x38003800}, + { 0xf72, 0x38383838}, + { 0x983, 0x3c000000}, + { 0xda3, 0x3c003c00}, + { 0xfb3, 0x3c3c3c3c}, + { 0x9c4, 0x3e000000}, + { 0xde4, 0x3e003e00}, + { 0xff4, 0x3e3e3e3e}, + { 0xa05, 0x3f000000}, + { 0xe25, 0x3f003f00}, + { 0xe35, 0x3f3f3f3f}, + { 0xa46, 0x3f800000}, + { 0xe66, 0x3f803f80}, + { 0xa87, 0x3fc00000}, + { 0xea7, 0x3fc03fc0}, + { 0xac8, 0x3fe00000}, + { 0xee8, 0x3fe03fe0}, + { 0xb09, 0x3ff00000}, + { 0xf29, 0x3ff03ff0}, + { 0xb4a, 0x3ff80000}, + { 0xf6a, 0x3ff83ff8}, + { 0xb8b, 0x3ffc0000}, + { 0xfab, 0x3ffc3ffc}, + { 0xbcc, 0x3ffe0000}, + { 0xfec, 0x3ffe3ffe}, + { 0xc0d, 0x3fff0000}, + { 0xc2d, 0x3fff3fff}, + { 0xc4e, 0x3fff8000}, + { 0xc8f, 0x3fffc000}, + { 0xcd0, 0x3fffe000}, + { 0xd11, 0x3ffff000}, + { 0xd52, 0x3ffff800}, + { 0xd93, 0x3ffffc00}, + { 0xdd4, 0x3ffffe00}, + { 0xe15, 0x3fffff00}, + { 0xe56, 0x3fffff80}, + { 0xe97, 0x3fffffc0}, + { 0xed8, 0x3fffffe0}, + { 0xf19, 0x3ffffff0}, + { 0xf5a, 0x3ffffff8}, + { 0xf9b, 0x3ffffffc}, + { 0xfdc, 0x3ffffffe}, + { 0x81d, 0x3fffffff}, + { 0x880, 0x40000000}, + { 0xca0, 0x40004000}, + { 0xeb0, 0x40404040}, + { 0xfb8, 0x44444444}, + { 0xfbc, 0x55555555}, + { 0x8c1, 0x60000000}, + { 0xce1, 0x60006000}, + { 0xef1, 0x60606060}, + { 0xff9, 0x66666666}, + { 0x902, 0x70000000}, + { 0xd22, 0x70007000}, + { 0xf32, 0x70707070}, + { 0xf3a, 0x77777777}, + { 0x943, 0x78000000}, + { 0xd63, 0x78007800}, + { 0xf73, 0x78787878}, + { 0x984, 0x7c000000}, + { 0xda4, 0x7c007c00}, + { 0xfb4, 0x7c7c7c7c}, + { 0x9c5, 0x7e000000}, + { 0xde5, 0x7e007e00}, + { 0xff5, 0x7e7e7e7e}, + { 0xa06, 0x7f000000}, + { 0xe26, 0x7f007f00}, + { 0xe36, 0x7f7f7f7f}, + { 0xa47, 0x7f800000}, + { 0xe67, 0x7f807f80}, + { 0xa88, 0x7fc00000}, + { 0xea8, 0x7fc07fc0}, + { 0xac9, 0x7fe00000}, + { 0xee9, 0x7fe07fe0}, + { 0xb0a, 0x7ff00000}, + { 0xf2a, 0x7ff07ff0}, + { 0xb4b, 0x7ff80000}, + { 0xf6b, 0x7ff87ff8}, + { 0xb8c, 0x7ffc0000}, + { 0xfac, 0x7ffc7ffc}, + { 0xbcd, 0x7ffe0000}, + { 0xfed, 0x7ffe7ffe}, + { 0xc0e, 0x7fff0000}, + { 0xc2e, 0x7fff7fff}, + { 0xc4f, 0x7fff8000}, + { 0xc90, 0x7fffc000}, + { 0xcd1, 0x7fffe000}, + { 0xd12, 0x7ffff000}, + { 0xd53, 0x7ffff800}, + { 0xd94, 0x7ffffc00}, + { 0xdd5, 0x7ffffe00}, + { 0xe16, 0x7fffff00}, + { 0xe57, 0x7fffff80}, + { 0xe98, 0x7fffffc0}, + { 0xed9, 0x7fffffe0}, + { 0xf1a, 0x7ffffff0}, + { 0xf5b, 0x7ffffff8}, + { 0xf9c, 0x7ffffffc}, + { 0xfdd, 0x7ffffffe}, + { 0x81e, 0x7fffffff}, + { 0x840, 0x80000000}, + { 0x841, 0x80000001}, + { 0x842, 0x80000003}, + { 0x843, 0x80000007}, + { 0x844, 0x8000000f}, + { 0x845, 0x8000001f}, + { 0x846, 0x8000003f}, + { 0x847, 0x8000007f}, + { 0x848, 0x800000ff}, + { 0x849, 0x800001ff}, + { 0x84a, 0x800003ff}, + { 0x84b, 0x800007ff}, + { 0x84c, 0x80000fff}, + { 0x84d, 0x80001fff}, + { 0x84e, 0x80003fff}, + { 0x84f, 0x80007fff}, + { 0xc60, 0x80008000}, + { 0x850, 0x8000ffff}, + { 0xc61, 0x80018001}, + { 0x851, 0x8001ffff}, + { 0xc62, 0x80038003}, + { 0x852, 0x8003ffff}, + { 0xc63, 0x80078007}, + { 0x853, 0x8007ffff}, + { 0xc64, 0x800f800f}, + { 0x854, 0x800fffff}, + { 0xc65, 0x801f801f}, + { 0x855, 0x801fffff}, + { 0xc66, 0x803f803f}, + { 0x856, 0x803fffff}, + { 0xc67, 0x807f807f}, + { 0x857, 0x807fffff}, + { 0xe70, 0x80808080}, + { 0xc68, 0x80ff80ff}, + { 0x858, 0x80ffffff}, + { 0xe71, 0x81818181}, + { 0xc69, 0x81ff81ff}, + { 0x859, 0x81ffffff}, + { 0xe72, 0x83838383}, + { 0xc6a, 0x83ff83ff}, + { 0x85a, 0x83ffffff}, + { 0xe73, 0x87878787}, + { 0xc6b, 0x87ff87ff}, + { 0x85b, 0x87ffffff}, + { 0xf78, 0x88888888}, + { 0xe74, 0x8f8f8f8f}, + { 0xc6c, 0x8fff8fff}, + { 0x85c, 0x8fffffff}, + { 0xf79, 0x99999999}, + { 0xe75, 0x9f9f9f9f}, + { 0xc6d, 0x9fff9fff}, + { 0x85d, 0x9fffffff}, + { 0xffc, 0xaaaaaaaa}, + { 0xf7a, 0xbbbbbbbb}, + { 0xe76, 0xbfbfbfbf}, + { 0xc6e, 0xbfffbfff}, + { 0x85e, 0xbfffffff}, + { 0x881, 0xc0000000}, + { 0x882, 0xc0000001}, + { 0x883, 0xc0000003}, + { 0x884, 0xc0000007}, + { 0x885, 0xc000000f}, + { 0x886, 0xc000001f}, + { 0x887, 0xc000003f}, + { 0x888, 0xc000007f}, + { 0x889, 0xc00000ff}, + { 0x88a, 0xc00001ff}, + { 0x88b, 0xc00003ff}, + { 0x88c, 0xc00007ff}, + { 0x88d, 0xc0000fff}, + { 0x88e, 0xc0001fff}, + { 0x88f, 0xc0003fff}, + { 0x890, 0xc0007fff}, + { 0xca1, 0xc000c000}, + { 0x891, 0xc000ffff}, + { 0xca2, 0xc001c001}, + { 0x892, 0xc001ffff}, + { 0xca3, 0xc003c003}, + { 0x893, 0xc003ffff}, + { 0xca4, 0xc007c007}, + { 0x894, 0xc007ffff}, + { 0xca5, 0xc00fc00f}, + { 0x895, 0xc00fffff}, + { 0xca6, 0xc01fc01f}, + { 0x896, 0xc01fffff}, + { 0xca7, 0xc03fc03f}, + { 0x897, 0xc03fffff}, + { 0xca8, 0xc07fc07f}, + { 0x898, 0xc07fffff}, + { 0xeb1, 0xc0c0c0c0}, + { 0xca9, 0xc0ffc0ff}, + { 0x899, 0xc0ffffff}, + { 0xeb2, 0xc1c1c1c1}, + { 0xcaa, 0xc1ffc1ff}, + { 0x89a, 0xc1ffffff}, + { 0xeb3, 0xc3c3c3c3}, + { 0xcab, 0xc3ffc3ff}, + { 0x89b, 0xc3ffffff}, + { 0xeb4, 0xc7c7c7c7}, + { 0xcac, 0xc7ffc7ff}, + { 0x89c, 0xc7ffffff}, + { 0xfb9, 0xcccccccc}, + { 0xeb5, 0xcfcfcfcf}, + { 0xcad, 0xcfffcfff}, + { 0x89d, 0xcfffffff}, + { 0xfba, 0xdddddddd}, + { 0xeb6, 0xdfdfdfdf}, + { 0xcae, 0xdfffdfff}, + { 0x89e, 0xdfffffff}, + { 0x8c2, 0xe0000000}, + { 0x8c3, 0xe0000001}, + { 0x8c4, 0xe0000003}, + { 0x8c5, 0xe0000007}, + { 0x8c6, 0xe000000f}, + { 0x8c7, 0xe000001f}, + { 0x8c8, 0xe000003f}, + { 0x8c9, 0xe000007f}, + { 0x8ca, 0xe00000ff}, + { 0x8cb, 0xe00001ff}, + { 0x8cc, 0xe00003ff}, + { 0x8cd, 0xe00007ff}, + { 0x8ce, 0xe0000fff}, + { 0x8cf, 0xe0001fff}, + { 0x8d0, 0xe0003fff}, + { 0x8d1, 0xe0007fff}, + { 0xce2, 0xe000e000}, + { 0x8d2, 0xe000ffff}, + { 0xce3, 0xe001e001}, + { 0x8d3, 0xe001ffff}, + { 0xce4, 0xe003e003}, + { 0x8d4, 0xe003ffff}, + { 0xce5, 0xe007e007}, + { 0x8d5, 0xe007ffff}, + { 0xce6, 0xe00fe00f}, + { 0x8d6, 0xe00fffff}, + { 0xce7, 0xe01fe01f}, + { 0x8d7, 0xe01fffff}, + { 0xce8, 0xe03fe03f}, + { 0x8d8, 0xe03fffff}, + { 0xce9, 0xe07fe07f}, + { 0x8d9, 0xe07fffff}, + { 0xef2, 0xe0e0e0e0}, + { 0xcea, 0xe0ffe0ff}, + { 0x8da, 0xe0ffffff}, + { 0xef3, 0xe1e1e1e1}, + { 0xceb, 0xe1ffe1ff}, + { 0x8db, 0xe1ffffff}, + { 0xef4, 0xe3e3e3e3}, + { 0xcec, 0xe3ffe3ff}, + { 0x8dc, 0xe3ffffff}, + { 0xef5, 0xe7e7e7e7}, + { 0xced, 0xe7ffe7ff}, + { 0x8dd, 0xe7ffffff}, + { 0xffa, 0xeeeeeeee}, + { 0xef6, 0xefefefef}, + { 0xcee, 0xefffefff}, + { 0x8de, 0xefffffff}, + { 0x903, 0xf0000000}, + { 0x904, 0xf0000001}, + { 0x905, 0xf0000003}, + { 0x906, 0xf0000007}, + { 0x907, 0xf000000f}, + { 0x908, 0xf000001f}, + { 0x909, 0xf000003f}, + { 0x90a, 0xf000007f}, + { 0x90b, 0xf00000ff}, + { 0x90c, 0xf00001ff}, + { 0x90d, 0xf00003ff}, + { 0x90e, 0xf00007ff}, + { 0x90f, 0xf0000fff}, + { 0x910, 0xf0001fff}, + { 0x911, 0xf0003fff}, + { 0x912, 0xf0007fff}, + { 0xd23, 0xf000f000}, + { 0x913, 0xf000ffff}, + { 0xd24, 0xf001f001}, + { 0x914, 0xf001ffff}, + { 0xd25, 0xf003f003}, + { 0x915, 0xf003ffff}, + { 0xd26, 0xf007f007}, + { 0x916, 0xf007ffff}, + { 0xd27, 0xf00ff00f}, + { 0x917, 0xf00fffff}, + { 0xd28, 0xf01ff01f}, + { 0x918, 0xf01fffff}, + { 0xd29, 0xf03ff03f}, + { 0x919, 0xf03fffff}, + { 0xd2a, 0xf07ff07f}, + { 0x91a, 0xf07fffff}, + { 0xf33, 0xf0f0f0f0}, + { 0xd2b, 0xf0fff0ff}, + { 0x91b, 0xf0ffffff}, + { 0xf34, 0xf1f1f1f1}, + { 0xd2c, 0xf1fff1ff}, + { 0x91c, 0xf1ffffff}, + { 0xf35, 0xf3f3f3f3}, + { 0xd2d, 0xf3fff3ff}, + { 0x91d, 0xf3ffffff}, + { 0xf36, 0xf7f7f7f7}, + { 0xd2e, 0xf7fff7ff}, + { 0x91e, 0xf7ffffff}, + { 0x944, 0xf8000000}, + { 0x945, 0xf8000001}, + { 0x946, 0xf8000003}, + { 0x947, 0xf8000007}, + { 0x948, 0xf800000f}, + { 0x949, 0xf800001f}, + { 0x94a, 0xf800003f}, + { 0x94b, 0xf800007f}, + { 0x94c, 0xf80000ff}, + { 0x94d, 0xf80001ff}, + { 0x94e, 0xf80003ff}, + { 0x94f, 0xf80007ff}, + { 0x950, 0xf8000fff}, + { 0x951, 0xf8001fff}, + { 0x952, 0xf8003fff}, + { 0x953, 0xf8007fff}, + { 0xd64, 0xf800f800}, + { 0x954, 0xf800ffff}, + { 0xd65, 0xf801f801}, + { 0x955, 0xf801ffff}, + { 0xd66, 0xf803f803}, + { 0x956, 0xf803ffff}, + { 0xd67, 0xf807f807}, + { 0x957, 0xf807ffff}, + { 0xd68, 0xf80ff80f}, + { 0x958, 0xf80fffff}, + { 0xd69, 0xf81ff81f}, + { 0x959, 0xf81fffff}, + { 0xd6a, 0xf83ff83f}, + { 0x95a, 0xf83fffff}, + { 0xd6b, 0xf87ff87f}, + { 0x95b, 0xf87fffff}, + { 0xf74, 0xf8f8f8f8}, + { 0xd6c, 0xf8fff8ff}, + { 0x95c, 0xf8ffffff}, + { 0xf75, 0xf9f9f9f9}, + { 0xd6d, 0xf9fff9ff}, + { 0x95d, 0xf9ffffff}, + { 0xf76, 0xfbfbfbfb}, + { 0xd6e, 0xfbfffbff}, + { 0x95e, 0xfbffffff}, + { 0x985, 0xfc000000}, + { 0x986, 0xfc000001}, + { 0x987, 0xfc000003}, + { 0x988, 0xfc000007}, + { 0x989, 0xfc00000f}, + { 0x98a, 0xfc00001f}, + { 0x98b, 0xfc00003f}, + { 0x98c, 0xfc00007f}, + { 0x98d, 0xfc0000ff}, + { 0x98e, 0xfc0001ff}, + { 0x98f, 0xfc0003ff}, + { 0x990, 0xfc0007ff}, + { 0x991, 0xfc000fff}, + { 0x992, 0xfc001fff}, + { 0x993, 0xfc003fff}, + { 0x994, 0xfc007fff}, + { 0xda5, 0xfc00fc00}, + { 0x995, 0xfc00ffff}, + { 0xda6, 0xfc01fc01}, + { 0x996, 0xfc01ffff}, + { 0xda7, 0xfc03fc03}, + { 0x997, 0xfc03ffff}, + { 0xda8, 0xfc07fc07}, + { 0x998, 0xfc07ffff}, + { 0xda9, 0xfc0ffc0f}, + { 0x999, 0xfc0fffff}, + { 0xdaa, 0xfc1ffc1f}, + { 0x99a, 0xfc1fffff}, + { 0xdab, 0xfc3ffc3f}, + { 0x99b, 0xfc3fffff}, + { 0xdac, 0xfc7ffc7f}, + { 0x99c, 0xfc7fffff}, + { 0xfb5, 0xfcfcfcfc}, + { 0xdad, 0xfcfffcff}, + { 0x99d, 0xfcffffff}, + { 0xfb6, 0xfdfdfdfd}, + { 0xdae, 0xfdfffdff}, + { 0x99e, 0xfdffffff}, + { 0x9c6, 0xfe000000}, + { 0x9c7, 0xfe000001}, + { 0x9c8, 0xfe000003}, + { 0x9c9, 0xfe000007}, + { 0x9ca, 0xfe00000f}, + { 0x9cb, 0xfe00001f}, + { 0x9cc, 0xfe00003f}, + { 0x9cd, 0xfe00007f}, + { 0x9ce, 0xfe0000ff}, + { 0x9cf, 0xfe0001ff}, + { 0x9d0, 0xfe0003ff}, + { 0x9d1, 0xfe0007ff}, + { 0x9d2, 0xfe000fff}, + { 0x9d3, 0xfe001fff}, + { 0x9d4, 0xfe003fff}, + { 0x9d5, 0xfe007fff}, + { 0xde6, 0xfe00fe00}, + { 0x9d6, 0xfe00ffff}, + { 0xde7, 0xfe01fe01}, + { 0x9d7, 0xfe01ffff}, + { 0xde8, 0xfe03fe03}, + { 0x9d8, 0xfe03ffff}, + { 0xde9, 0xfe07fe07}, + { 0x9d9, 0xfe07ffff}, + { 0xdea, 0xfe0ffe0f}, + { 0x9da, 0xfe0fffff}, + { 0xdeb, 0xfe1ffe1f}, + { 0x9db, 0xfe1fffff}, + { 0xdec, 0xfe3ffe3f}, + { 0x9dc, 0xfe3fffff}, + { 0xded, 0xfe7ffe7f}, + { 0x9dd, 0xfe7fffff}, + { 0xff6, 0xfefefefe}, + { 0xdee, 0xfefffeff}, + { 0x9de, 0xfeffffff}, + { 0xa07, 0xff000000}, + { 0xa08, 0xff000001}, + { 0xa09, 0xff000003}, + { 0xa0a, 0xff000007}, + { 0xa0b, 0xff00000f}, + { 0xa0c, 0xff00001f}, + { 0xa0d, 0xff00003f}, + { 0xa0e, 0xff00007f}, + { 0xa0f, 0xff0000ff}, + { 0xa10, 0xff0001ff}, + { 0xa11, 0xff0003ff}, + { 0xa12, 0xff0007ff}, + { 0xa13, 0xff000fff}, + { 0xa14, 0xff001fff}, + { 0xa15, 0xff003fff}, + { 0xa16, 0xff007fff}, + { 0xe27, 0xff00ff00}, + { 0xa17, 0xff00ffff}, + { 0xe28, 0xff01ff01}, + { 0xa18, 0xff01ffff}, + { 0xe29, 0xff03ff03}, + { 0xa19, 0xff03ffff}, + { 0xe2a, 0xff07ff07}, + { 0xa1a, 0xff07ffff}, + { 0xe2b, 0xff0fff0f}, + { 0xa1b, 0xff0fffff}, + { 0xe2c, 0xff1fff1f}, + { 0xa1c, 0xff1fffff}, + { 0xe2d, 0xff3fff3f}, + { 0xa1d, 0xff3fffff}, + { 0xe2e, 0xff7fff7f}, + { 0xa1e, 0xff7fffff}, + { 0xa48, 0xff800000}, + { 0xa49, 0xff800001}, + { 0xa4a, 0xff800003}, + { 0xa4b, 0xff800007}, + { 0xa4c, 0xff80000f}, + { 0xa4d, 0xff80001f}, + { 0xa4e, 0xff80003f}, + { 0xa4f, 0xff80007f}, + { 0xa50, 0xff8000ff}, + { 0xa51, 0xff8001ff}, + { 0xa52, 0xff8003ff}, + { 0xa53, 0xff8007ff}, + { 0xa54, 0xff800fff}, + { 0xa55, 0xff801fff}, + { 0xa56, 0xff803fff}, + { 0xa57, 0xff807fff}, + { 0xe68, 0xff80ff80}, + { 0xa58, 0xff80ffff}, + { 0xe69, 0xff81ff81}, + { 0xa59, 0xff81ffff}, + { 0xe6a, 0xff83ff83}, + { 0xa5a, 0xff83ffff}, + { 0xe6b, 0xff87ff87}, + { 0xa5b, 0xff87ffff}, + { 0xe6c, 0xff8fff8f}, + { 0xa5c, 0xff8fffff}, + { 0xe6d, 0xff9fff9f}, + { 0xa5d, 0xff9fffff}, + { 0xe6e, 0xffbfffbf}, + { 0xa5e, 0xffbfffff}, + { 0xa89, 0xffc00000}, + { 0xa8a, 0xffc00001}, + { 0xa8b, 0xffc00003}, + { 0xa8c, 0xffc00007}, + { 0xa8d, 0xffc0000f}, + { 0xa8e, 0xffc0001f}, + { 0xa8f, 0xffc0003f}, + { 0xa90, 0xffc0007f}, + { 0xa91, 0xffc000ff}, + { 0xa92, 0xffc001ff}, + { 0xa93, 0xffc003ff}, + { 0xa94, 0xffc007ff}, + { 0xa95, 0xffc00fff}, + { 0xa96, 0xffc01fff}, + { 0xa97, 0xffc03fff}, + { 0xa98, 0xffc07fff}, + { 0xea9, 0xffc0ffc0}, + { 0xa99, 0xffc0ffff}, + { 0xeaa, 0xffc1ffc1}, + { 0xa9a, 0xffc1ffff}, + { 0xeab, 0xffc3ffc3}, + { 0xa9b, 0xffc3ffff}, + { 0xeac, 0xffc7ffc7}, + { 0xa9c, 0xffc7ffff}, + { 0xead, 0xffcfffcf}, + { 0xa9d, 0xffcfffff}, + { 0xeae, 0xffdfffdf}, + { 0xa9e, 0xffdfffff}, + { 0xaca, 0xffe00000}, + { 0xacb, 0xffe00001}, + { 0xacc, 0xffe00003}, + { 0xacd, 0xffe00007}, + { 0xace, 0xffe0000f}, + { 0xacf, 0xffe0001f}, + { 0xad0, 0xffe0003f}, + { 0xad1, 0xffe0007f}, + { 0xad2, 0xffe000ff}, + { 0xad3, 0xffe001ff}, + { 0xad4, 0xffe003ff}, + { 0xad5, 0xffe007ff}, + { 0xad6, 0xffe00fff}, + { 0xad7, 0xffe01fff}, + { 0xad8, 0xffe03fff}, + { 0xad9, 0xffe07fff}, + { 0xeea, 0xffe0ffe0}, + { 0xada, 0xffe0ffff}, + { 0xeeb, 0xffe1ffe1}, + { 0xadb, 0xffe1ffff}, + { 0xeec, 0xffe3ffe3}, + { 0xadc, 0xffe3ffff}, + { 0xeed, 0xffe7ffe7}, + { 0xadd, 0xffe7ffff}, + { 0xeee, 0xffefffef}, + { 0xade, 0xffefffff}, + { 0xb0b, 0xfff00000}, + { 0xb0c, 0xfff00001}, + { 0xb0d, 0xfff00003}, + { 0xb0e, 0xfff00007}, + { 0xb0f, 0xfff0000f}, + { 0xb10, 0xfff0001f}, + { 0xb11, 0xfff0003f}, + { 0xb12, 0xfff0007f}, + { 0xb13, 0xfff000ff}, + { 0xb14, 0xfff001ff}, + { 0xb15, 0xfff003ff}, + { 0xb16, 0xfff007ff}, + { 0xb17, 0xfff00fff}, + { 0xb18, 0xfff01fff}, + { 0xb19, 0xfff03fff}, + { 0xb1a, 0xfff07fff}, + { 0xf2b, 0xfff0fff0}, + { 0xb1b, 0xfff0ffff}, + { 0xf2c, 0xfff1fff1}, + { 0xb1c, 0xfff1ffff}, + { 0xf2d, 0xfff3fff3}, + { 0xb1d, 0xfff3ffff}, + { 0xf2e, 0xfff7fff7}, + { 0xb1e, 0xfff7ffff}, + { 0xb4c, 0xfff80000}, + { 0xb4d, 0xfff80001}, + { 0xb4e, 0xfff80003}, + { 0xb4f, 0xfff80007}, + { 0xb50, 0xfff8000f}, + { 0xb51, 0xfff8001f}, + { 0xb52, 0xfff8003f}, + { 0xb53, 0xfff8007f}, + { 0xb54, 0xfff800ff}, + { 0xb55, 0xfff801ff}, + { 0xb56, 0xfff803ff}, + { 0xb57, 0xfff807ff}, + { 0xb58, 0xfff80fff}, + { 0xb59, 0xfff81fff}, + { 0xb5a, 0xfff83fff}, + { 0xb5b, 0xfff87fff}, + { 0xf6c, 0xfff8fff8}, + { 0xb5c, 0xfff8ffff}, + { 0xf6d, 0xfff9fff9}, + { 0xb5d, 0xfff9ffff}, + { 0xf6e, 0xfffbfffb}, + { 0xb5e, 0xfffbffff}, + { 0xb8d, 0xfffc0000}, + { 0xb8e, 0xfffc0001}, + { 0xb8f, 0xfffc0003}, + { 0xb90, 0xfffc0007}, + { 0xb91, 0xfffc000f}, + { 0xb92, 0xfffc001f}, + { 0xb93, 0xfffc003f}, + { 0xb94, 0xfffc007f}, + { 0xb95, 0xfffc00ff}, + { 0xb96, 0xfffc01ff}, + { 0xb97, 0xfffc03ff}, + { 0xb98, 0xfffc07ff}, + { 0xb99, 0xfffc0fff}, + { 0xb9a, 0xfffc1fff}, + { 0xb9b, 0xfffc3fff}, + { 0xb9c, 0xfffc7fff}, + { 0xfad, 0xfffcfffc}, + { 0xb9d, 0xfffcffff}, + { 0xfae, 0xfffdfffd}, + { 0xb9e, 0xfffdffff}, + { 0xbce, 0xfffe0000}, + { 0xbcf, 0xfffe0001}, + { 0xbd0, 0xfffe0003}, + { 0xbd1, 0xfffe0007}, + { 0xbd2, 0xfffe000f}, + { 0xbd3, 0xfffe001f}, + { 0xbd4, 0xfffe003f}, + { 0xbd5, 0xfffe007f}, + { 0xbd6, 0xfffe00ff}, + { 0xbd7, 0xfffe01ff}, + { 0xbd8, 0xfffe03ff}, + { 0xbd9, 0xfffe07ff}, + { 0xbda, 0xfffe0fff}, + { 0xbdb, 0xfffe1fff}, + { 0xbdc, 0xfffe3fff}, + { 0xbdd, 0xfffe7fff}, + { 0xfee, 0xfffefffe}, + { 0xbde, 0xfffeffff}, + { 0xc0f, 0xffff0000}, + { 0xc10, 0xffff0001}, + { 0xc11, 0xffff0003}, + { 0xc12, 0xffff0007}, + { 0xc13, 0xffff000f}, + { 0xc14, 0xffff001f}, + { 0xc15, 0xffff003f}, + { 0xc16, 0xffff007f}, + { 0xc17, 0xffff00ff}, + { 0xc18, 0xffff01ff}, + { 0xc19, 0xffff03ff}, + { 0xc1a, 0xffff07ff}, + { 0xc1b, 0xffff0fff}, + { 0xc1c, 0xffff1fff}, + { 0xc1d, 0xffff3fff}, + { 0xc1e, 0xffff7fff}, + { 0xc50, 0xffff8000}, + { 0xc51, 0xffff8001}, + { 0xc52, 0xffff8003}, + { 0xc53, 0xffff8007}, + { 0xc54, 0xffff800f}, + { 0xc55, 0xffff801f}, + { 0xc56, 0xffff803f}, + { 0xc57, 0xffff807f}, + { 0xc58, 0xffff80ff}, + { 0xc59, 0xffff81ff}, + { 0xc5a, 0xffff83ff}, + { 0xc5b, 0xffff87ff}, + { 0xc5c, 0xffff8fff}, + { 0xc5d, 0xffff9fff}, + { 0xc5e, 0xffffbfff}, + { 0xc91, 0xffffc000}, + { 0xc92, 0xffffc001}, + { 0xc93, 0xffffc003}, + { 0xc94, 0xffffc007}, + { 0xc95, 0xffffc00f}, + { 0xc96, 0xffffc01f}, + { 0xc97, 0xffffc03f}, + { 0xc98, 0xffffc07f}, + { 0xc99, 0xffffc0ff}, + { 0xc9a, 0xffffc1ff}, + { 0xc9b, 0xffffc3ff}, + { 0xc9c, 0xffffc7ff}, + { 0xc9d, 0xffffcfff}, + { 0xc9e, 0xffffdfff}, + { 0xcd2, 0xffffe000}, + { 0xcd3, 0xffffe001}, + { 0xcd4, 0xffffe003}, + { 0xcd5, 0xffffe007}, + { 0xcd6, 0xffffe00f}, + { 0xcd7, 0xffffe01f}, + { 0xcd8, 0xffffe03f}, + { 0xcd9, 0xffffe07f}, + { 0xcda, 0xffffe0ff}, + { 0xcdb, 0xffffe1ff}, + { 0xcdc, 0xffffe3ff}, + { 0xcdd, 0xffffe7ff}, + { 0xcde, 0xffffefff}, + { 0xd13, 0xfffff000}, + { 0xd14, 0xfffff001}, + { 0xd15, 0xfffff003}, + { 0xd16, 0xfffff007}, + { 0xd17, 0xfffff00f}, + { 0xd18, 0xfffff01f}, + { 0xd19, 0xfffff03f}, + { 0xd1a, 0xfffff07f}, + { 0xd1b, 0xfffff0ff}, + { 0xd1c, 0xfffff1ff}, + { 0xd1d, 0xfffff3ff}, + { 0xd1e, 0xfffff7ff}, + { 0xd54, 0xfffff800}, + { 0xd55, 0xfffff801}, + { 0xd56, 0xfffff803}, + { 0xd57, 0xfffff807}, + { 0xd58, 0xfffff80f}, + { 0xd59, 0xfffff81f}, + { 0xd5a, 0xfffff83f}, + { 0xd5b, 0xfffff87f}, + { 0xd5c, 0xfffff8ff}, + { 0xd5d, 0xfffff9ff}, + { 0xd5e, 0xfffffbff}, + { 0xd95, 0xfffffc00}, + { 0xd96, 0xfffffc01}, + { 0xd97, 0xfffffc03}, + { 0xd98, 0xfffffc07}, + { 0xd99, 0xfffffc0f}, + { 0xd9a, 0xfffffc1f}, + { 0xd9b, 0xfffffc3f}, + { 0xd9c, 0xfffffc7f}, + { 0xd9d, 0xfffffcff}, + { 0xd9e, 0xfffffdff}, + { 0xdd6, 0xfffffe00}, + { 0xdd7, 0xfffffe01}, + { 0xdd8, 0xfffffe03}, + { 0xdd9, 0xfffffe07}, + { 0xdda, 0xfffffe0f}, + { 0xddb, 0xfffffe1f}, + { 0xddc, 0xfffffe3f}, + { 0xddd, 0xfffffe7f}, + { 0xdde, 0xfffffeff}, + { 0xe17, 0xffffff00}, + { 0xe18, 0xffffff01}, + { 0xe19, 0xffffff03}, + { 0xe1a, 0xffffff07}, + { 0xe1b, 0xffffff0f}, + { 0xe1c, 0xffffff1f}, + { 0xe1d, 0xffffff3f}, + { 0xe1e, 0xffffff7f}, + { 0xe58, 0xffffff80}, + { 0xe59, 0xffffff81}, + { 0xe5a, 0xffffff83}, + { 0xe5b, 0xffffff87}, + { 0xe5c, 0xffffff8f}, + { 0xe5d, 0xffffff9f}, + { 0xe5e, 0xffffffbf}, + { 0xe99, 0xffffffc0}, + { 0xe9a, 0xffffffc1}, + { 0xe9b, 0xffffffc3}, + { 0xe9c, 0xffffffc7}, + { 0xe9d, 0xffffffcf}, + { 0xe9e, 0xffffffdf}, + { 0xeda, 0xffffffe0}, + { 0xedb, 0xffffffe1}, + { 0xedc, 0xffffffe3}, + { 0xedd, 0xffffffe7}, + { 0xede, 0xffffffef}, + { 0xf1b, 0xfffffff0}, + { 0xf1c, 0xfffffff1}, + { 0xf1d, 0xfffffff3}, + { 0xf1e, 0xfffffff7}, + { 0xf5c, 0xfffffff8}, + { 0xf5d, 0xfffffff9}, + { 0xf5e, 0xfffffffb}, + { 0xf9d, 0xfffffffc}, + { 0xf9e, 0xfffffffd}, + { 0xfde, 0xfffffffe}, }; -uint32_t host_arm64_find_imm(uint32_t data) +uint32_t +host_arm64_find_imm(uint32_t data) { - int l = 0, r = IMM_NR - 1; + int l = 0, r = IMM_NR - 1; - while (l <= r) - { - int m = (l + r) >> 1; + while (l <= r) { + int m = (l + r) >> 1; - if (imm_table[m][1] < data) - l = m+1; - else if (imm_table[m][1] > data) - r = m-1; - else - return imm_table[m][0]; - } - return 0; + if (imm_table[m][1] < data) + l = m + 1; + else if (imm_table[m][1] > data) + r = m - 1; + else + return imm_table[m][0]; + } + return 0; } diff --git a/src/codegen_new/codegen_backend_arm64_ops.c b/src/codegen_new/codegen_backend_arm64_ops.c index 0cc20d788..aa5e5870a 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.c +++ b/src/codegen_new/codegen_backend_arm64_ops.c @@ -1,1380 +1,1516 @@ #if defined __aarch64__ || defined _M_ARM64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm64_defs.h" -#include "codegen_backend_arm64_ops.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm64_defs.h" +# include "codegen_backend_arm64_ops.h" +# define Rt(x) (x) +# define Rd(x) (x) +# define Rn(x) ((x) << 5) +# define Rt2(x) ((x) << 10) +# define Rm(x) ((x) << 16) -#define Rt(x) (x) -#define Rd(x) (x) -#define Rn(x) ((x) << 5) -#define Rt2(x) ((x) << 10) -#define Rm(x) ((x) << 16) +# define shift_imm6(x) ((x) << 10) -#define shift_imm6(x) ((x) << 10) +# define DATA_OFFSET_UP (1 << 23) +# define DATA_OFFSET_DOWN (0 << 23) -#define DATA_OFFSET_UP (1 << 23) -#define DATA_OFFSET_DOWN (0 << 23) +# define COND_EQ (0x0) +# define COND_NE (0x1) +# define COND_CS (0x2) +# define COND_CC (0x3) +# define COND_MI (0x4) +# define COND_PL (0x5) +# define COND_VS (0x6) +# define COND_VC (0x7) +# define COND_HI (0x8) +# define COND_LS (0x9) +# define COND_GE (0xa) +# define COND_LT (0xb) +# define COND_GT (0xc) +# define COND_LE (0xd) -#define COND_EQ (0x0) -#define COND_NE (0x1) -#define COND_CS (0x2) -#define COND_CC (0x3) -#define COND_MI (0x4) -#define COND_PL (0x5) -#define COND_VS (0x6) -#define COND_VC (0x7) -#define COND_HI (0x8) -#define COND_LS (0x9) -#define COND_GE (0xa) -#define COND_LT (0xb) -#define COND_GT (0xc) -#define COND_LE (0xd) +# define CSEL_COND(cond) ((cond) << 12) -#define CSEL_COND(cond) ((cond) << 12) +# define OPCODE_SHIFT 24 +# define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) +# define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) +# define OPCODE_ADR (0x10 << OPCODE_SHIFT) +# define OPCODE_B (0x14 << OPCODE_SHIFT) +# define OPCODE_BCOND (0x54 << OPCODE_SHIFT) +# define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) +# define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) +# define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) +# define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) +# define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) +# define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) +# define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) +# define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) +# define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) +# define OPCODE_TBZ (0x36 << OPCODE_SHIFT) -#define OPCODE_SHIFT 24 -#define OPCODE_ADD_IMM (0x11 << OPCODE_SHIFT) -#define OPCODE_ADDX_IMM (0x91 << OPCODE_SHIFT) -#define OPCODE_ADR (0x10 << OPCODE_SHIFT) -#define OPCODE_B (0x14 << OPCODE_SHIFT) -#define OPCODE_BCOND (0x54 << OPCODE_SHIFT) -#define OPCODE_CBNZ (0xb5 << OPCODE_SHIFT) -#define OPCODE_CBZ (0xb4 << OPCODE_SHIFT) -#define OPCODE_CMN_IMM (0x31 << OPCODE_SHIFT) -#define OPCODE_CMNX_IMM (0xb1 << OPCODE_SHIFT) -#define OPCODE_CMP_IMM (0x71 << OPCODE_SHIFT) -#define OPCODE_CMPX_IMM (0xf1 << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_SUBX_IMM (0xd1 << OPCODE_SHIFT) -#define OPCODE_TBNZ (0x37 << OPCODE_SHIFT) -#define OPCODE_TBZ (0x36 << OPCODE_SHIFT) +# define OPCODE_AND_IMM (0x024 << 23) +# define OPCODE_ANDS_IMM (0x0e4 << 23) +# define OPCODE_EOR_IMM (0x0a4 << 23) +# define OPCODE_MOVK_W (0x0e5 << 23) +# define OPCODE_MOVK_X (0x1e5 << 23) +# define OPCODE_MOVZ_W (0x0a5 << 23) +# define OPCODE_MOVZ_X (0x1a5 << 23) +# define OPCODE_ORR_IMM (0x064 << 23) -#define OPCODE_AND_IMM (0x024 << 23) -#define OPCODE_ANDS_IMM (0x0e4 << 23) -#define OPCODE_EOR_IMM (0x0a4 << 23) -#define OPCODE_MOVK_W (0x0e5 << 23) -#define OPCODE_MOVK_X (0x1e5 << 23) -#define OPCODE_MOVZ_W (0x0a5 << 23) -#define OPCODE_MOVZ_X (0x1a5 << 23) -#define OPCODE_ORR_IMM (0x064 << 23) +# define OPCODE_BFI (0x0cc << 22) +# define OPCODE_LDR_IMM_W (0x2e5 << 22) +# define OPCODE_LDR_IMM_X (0x3e5 << 22) +# define OPCODE_LDR_IMM_F64 (0x3f5 << 22) +# define OPCODE_LDRB_IMM_W (0x0e5 << 22) +# define OPCODE_LDRH_IMM (0x1e5 << 22) +# define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) +# define OPCODE_SBFX (0x04c << 22) +# define OPCODE_STP_PREIDX_X (0x2a6 << 22) +# define OPCODE_STR_IMM_W (0x2e4 << 22) +# define OPCODE_STR_IMM_Q (0x3e4 << 22) +# define OPCODE_STR_IMM_F64 (0x3f4 << 22) +# define OPCODE_STRB_IMM (0x0e4 << 22) +# define OPCODE_STRH_IMM (0x1e4 << 22) +# define OPCODE_UBFX (0x14c << 22) -#define OPCODE_BFI (0x0cc << 22) -#define OPCODE_LDR_IMM_W (0x2e5 << 22) -#define OPCODE_LDR_IMM_X (0x3e5 << 22) -#define OPCODE_LDR_IMM_F64 (0x3f5 << 22) -#define OPCODE_LDRB_IMM_W (0x0e5 << 22) -#define OPCODE_LDRH_IMM (0x1e5 << 22) -#define OPCODE_LDP_POSTIDX_X (0x2a3 << 22) -#define OPCODE_SBFX (0x04c << 22) -#define OPCODE_STP_PREIDX_X (0x2a6 << 22) -#define OPCODE_STR_IMM_W (0x2e4 << 22) -#define OPCODE_STR_IMM_Q (0x3e4 << 22) -#define OPCODE_STR_IMM_F64 (0x3f4 << 22) -#define OPCODE_STRB_IMM (0x0e4 << 22) -#define OPCODE_STRH_IMM (0x1e4 << 22) -#define OPCODE_UBFX (0x14c << 22) +# define OPCODE_ADD_LSL (0x058 << 21) +# define OPCODE_ADD_LSR (0x05a << 21) +# define OPCODE_ADDX_LSL (0x458 << 21) +# define OPCODE_AND_ASR (0x054 << 21) +# define OPCODE_AND_LSL (0x050 << 21) +# define OPCODE_AND_ROR (0x056 << 21) +# define OPCODE_ANDS_LSL (0x350 << 21) +# define OPCODE_CMP_LSL (0x358 << 21) +# define OPCODE_CSEL (0x0d4 << 21) +# define OPCODE_EOR_LSL (0x250 << 21) +# define OPCODE_ORR_ASR (0x154 << 21) +# define OPCODE_ORR_LSL (0x150 << 21) +# define OPCODE_ORR_LSR (0x152 << 21) +# define OPCODE_ORR_ROR (0x156 << 21) +# define OPCODE_ORRX_LSL (0x550 << 21) +# define OPCODE_SUB_LSL (0x258 << 21) +# define OPCODE_SUB_LSR (0x25a << 21) +# define OPCODE_SUBX_LSL (0x658 << 21) -#define OPCODE_ADD_LSL (0x058 << 21) -#define OPCODE_ADD_LSR (0x05a << 21) -#define OPCODE_ADDX_LSL (0x458 << 21) -#define OPCODE_AND_ASR (0x054 << 21) -#define OPCODE_AND_LSL (0x050 << 21) -#define OPCODE_AND_ROR (0x056 << 21) -#define OPCODE_ANDS_LSL (0x350 << 21) -#define OPCODE_CMP_LSL (0x358 << 21) -#define OPCODE_CSEL (0x0d4 << 21) -#define OPCODE_EOR_LSL (0x250 << 21) -#define OPCODE_ORR_ASR (0x154 << 21) -#define OPCODE_ORR_LSL (0x150 << 21) -#define OPCODE_ORR_LSR (0x152 << 21) -#define OPCODE_ORR_ROR (0x156 << 21) -#define OPCODE_ORRX_LSL (0x550 << 21) -#define OPCODE_SUB_LSL (0x258 << 21) -#define OPCODE_SUB_LSR (0x25a << 21) -#define OPCODE_SUBX_LSL (0x658 << 21) +# define OPCODE_ADD_V8B (0x0e208400) +# define OPCODE_ADD_V4H (0x0e608400) +# define OPCODE_ADD_V2S (0x0ea08400) +# define OPCODE_ADDP_V4S (0x4ea0bc00) +# define OPCODE_AND_V (0x0e201c00) +# define OPCODE_ASR (0x1ac02800) +# define OPCODE_BIC_V (0x0e601c00) +# define OPCODE_BLR (0xd63f0000) +# define OPCODE_BR (0xd61f0000) +# define OPCODE_CMEQ_V8B (0x2e208c00) +# define OPCODE_CMEQ_V4H (0x2e608c00) +# define OPCODE_CMEQ_V2S (0x2ea08c00) +# define OPCODE_CMGT_V8B (0x0e203400) +# define OPCODE_CMGT_V4H (0x0e603400) +# define OPCODE_CMGT_V2S (0x0ea03400) +# define OPCODE_DUP_V2S (0x0e040400) +# define OPCODE_EOR_V (0x2e201c00) +# define OPCODE_FABS_D (0x1e60c000) +# define OPCODE_FADD_D (0x1e602800) +# define OPCODE_FADD_V2S (0x0e20d400) +# define OPCODE_FCMEQ_V2S (0x0e20e400) +# define OPCODE_FCMGE_V2S (0x2e20e400) +# define OPCODE_FCMGT_V2S (0x2ea0e400) +# define OPCODE_FCMP_D (0x1e602000) +# define OPCODE_FCVT_D_S (0x1e22c000) +# define OPCODE_FCVT_S_D (0x1e624000) +# define OPCODE_FCVTMS_W_D (0x1e700000) +# define OPCODE_FCVTMS_X_D (0x9e700000) +# define OPCODE_FCVTNS_W_D (0x1e600000) +# define OPCODE_FCVTNS_X_D (0x9e600000) +# define OPCODE_FCVTPS_W_D (0x1e680000) +# define OPCODE_FCVTPS_X_D (0x9e680000) +# define OPCODE_FCVTZS_W_D (0x1e780000) +# define OPCODE_FCVTZS_X_D (0x9e780000) +# define OPCODE_FCVTZS_V2S (0x0ea1b800) +# define OPCODE_FDIV_D (0x1e601800) +# define OPCODE_FDIV_S (0x1e201800) +# define OPCODE_FMAX_V2S (0x0e20f400) +# define OPCODE_FMIN_V2S (0x0ea0f400) +# define OPCODE_FMOV_D_D (0x1e604000) +# define OPCODE_FMOV_D_Q (0x9e670000) +# define OPCODE_FMOV_Q_D (0x9e660000) +# define OPCODE_FMOV_S_W (0x1e270000) +# define OPCODE_FMOV_W_S (0x1e260000) +# define OPCODE_FMOV_S_ONE (0x1e2e1000) +# define OPCODE_FMUL_D (0x1e600800) +# define OPCODE_FMUL_V2S (0x2e20dc00) +# define OPCODE_FNEG_D (0x1e614000) +# define OPCODE_FRINTX_D (0x1e674000) +# define OPCODE_FSQRT_D (0x1e61c000) +# define OPCODE_FSQRT_S (0x1e21c000) +# define OPCODE_FSUB_D (0x1e603800) +# define OPCODE_FSUB_V2S (0x0ea0d400) +# define OPCODE_LDR_REG (0xb8606800) +# define OPCODE_LDRX_REG (0xf8606800) +# define OPCODE_LDRB_REG (0x38606800) +# define OPCODE_LDRH_REG (0x78606800) +# define OPCODE_LDRX_REG_LSL3 (0xf8607800) +# define OPCODE_LDR_REG_F32 (0xbc606800) +# define OPCODE_LDR_REG_F64 (0xfc606800) +# define OPCODE_LDR_REG_F64_S (0xfc607800) +# define OPCODE_LSL (0x1ac02000) +# define OPCODE_LSR (0x1ac02400) +# define OPCODE_MSR_FPCR (0xd51b4400) +# define OPCODE_MUL_V4H (0x0e609c00) +# define OPCODE_NOP (0xd503201f) +# define OPCODE_ORR_V (0x0ea01c00) +# define OPCODE_RET (0xd65f0000) +# define OPCODE_ROR (0x1ac02c00) +# define OPCODE_SADDLP_V2S_4H (0x0e602800) +# define OPCODE_SCVTF_D_Q (0x9e620000) +# define OPCODE_SCVTF_D_W (0x1e620000) +# define OPCODE_SCVTF_V2S (0x0e21d800) +# define OPCODE_SQADD_V8B (0x0e200c00) +# define OPCODE_SQADD_V4H (0x0e600c00) +# define OPCODE_SQSUB_V8B (0x0e202c00) +# define OPCODE_SQSUB_V4H (0x0e602c00) +# define OPCODE_SQXTN_V8B_8H (0x0e214800) +# define OPCODE_SQXTN_V4H_4S (0x0e614800) +# define OPCODE_SHL_VD (0x0f005400) +# define OPCODE_SHL_VQ (0x4f005400) +# define OPCODE_SHRN (0x0f008400) +# define OPCODE_SMULL_V4S_4H (0x0e60c000) +# define OPCODE_SSHR_VD (0x0f000400) +# define OPCODE_SSHR_VQ (0x4f000400) +# define OPCODE_STR_REG (0xb8206800) +# define OPCODE_STRB_REG (0x38206800) +# define OPCODE_STRH_REG (0x78206800) +# define OPCODE_STR_REG_F32 (0xbc206800) +# define OPCODE_STR_REG_F64 (0xfc206800) +# define OPCODE_STR_REG_F64_S (0xfc207800) +# define OPCODE_SUB_V8B (0x2e208400) +# define OPCODE_SUB_V4H (0x2e608400) +# define OPCODE_SUB_V2S (0x2ea08400) +# define OPCODE_UQADD_V8B (0x2e200c00) +# define OPCODE_UQADD_V4H (0x2e600c00) +# define OPCODE_UQSUB_V8B (0x2e202c00) +# define OPCODE_UQSUB_V4H (0x2e602c00) +# define OPCODE_UQXTN_V8B_8H (0x2e214800) +# define OPCODE_UQXTN_V4H_4S (0x2e614800) +# define OPCODE_USHR_VD (0x2f000400) +# define OPCODE_USHR_VQ (0x6f000400) +# define OPCODE_ZIP1_V8B (0x0e003800) +# define OPCODE_ZIP1_V4H (0x0e403800) +# define OPCODE_ZIP1_V2S (0x0e803800) +# define OPCODE_ZIP2_V8B (0x0e007800) +# define OPCODE_ZIP2_V4H (0x0e407800) +# define OPCODE_ZIP2_V2S (0x0e807800) -#define OPCODE_ADD_V8B (0x0e208400) -#define OPCODE_ADD_V4H (0x0e608400) -#define OPCODE_ADD_V2S (0x0ea08400) -#define OPCODE_ADDP_V4S (0x4ea0bc00) -#define OPCODE_AND_V (0x0e201c00) -#define OPCODE_ASR (0x1ac02800) -#define OPCODE_BIC_V (0x0e601c00) -#define OPCODE_BLR (0xd63f0000) -#define OPCODE_BR (0xd61f0000) -#define OPCODE_CMEQ_V8B (0x2e208c00) -#define OPCODE_CMEQ_V4H (0x2e608c00) -#define OPCODE_CMEQ_V2S (0x2ea08c00) -#define OPCODE_CMGT_V8B (0x0e203400) -#define OPCODE_CMGT_V4H (0x0e603400) -#define OPCODE_CMGT_V2S (0x0ea03400) -#define OPCODE_DUP_V2S (0x0e040400) -#define OPCODE_EOR_V (0x2e201c00) -#define OPCODE_FABS_D (0x1e60c000) -#define OPCODE_FADD_D (0x1e602800) -#define OPCODE_FADD_V2S (0x0e20d400) -#define OPCODE_FCMEQ_V2S (0x0e20e400) -#define OPCODE_FCMGE_V2S (0x2e20e400) -#define OPCODE_FCMGT_V2S (0x2ea0e400) -#define OPCODE_FCMP_D (0x1e602000) -#define OPCODE_FCVT_D_S (0x1e22c000) -#define OPCODE_FCVT_S_D (0x1e624000) -#define OPCODE_FCVTMS_W_D (0x1e700000) -#define OPCODE_FCVTMS_X_D (0x9e700000) -#define OPCODE_FCVTNS_W_D (0x1e600000) -#define OPCODE_FCVTNS_X_D (0x9e600000) -#define OPCODE_FCVTPS_W_D (0x1e680000) -#define OPCODE_FCVTPS_X_D (0x9e680000) -#define OPCODE_FCVTZS_W_D (0x1e780000) -#define OPCODE_FCVTZS_X_D (0x9e780000) -#define OPCODE_FCVTZS_V2S (0x0ea1b800) -#define OPCODE_FDIV_D (0x1e601800) -#define OPCODE_FDIV_S (0x1e201800) -#define OPCODE_FMAX_V2S (0x0e20f400) -#define OPCODE_FMIN_V2S (0x0ea0f400) -#define OPCODE_FMOV_D_D (0x1e604000) -#define OPCODE_FMOV_D_Q (0x9e670000) -#define OPCODE_FMOV_Q_D (0x9e660000) -#define OPCODE_FMOV_S_W (0x1e270000) -#define OPCODE_FMOV_W_S (0x1e260000) -#define OPCODE_FMOV_S_ONE (0x1e2e1000) -#define OPCODE_FMUL_D (0x1e600800) -#define OPCODE_FMUL_V2S (0x2e20dc00) -#define OPCODE_FNEG_D (0x1e614000) -#define OPCODE_FRINTX_D (0x1e674000) -#define OPCODE_FSQRT_D (0x1e61c000) -#define OPCODE_FSQRT_S (0x1e21c000) -#define OPCODE_FSUB_D (0x1e603800) -#define OPCODE_FSUB_V2S (0x0ea0d400) -#define OPCODE_LDR_REG (0xb8606800) -#define OPCODE_LDRX_REG (0xf8606800) -#define OPCODE_LDRB_REG (0x38606800) -#define OPCODE_LDRH_REG (0x78606800) -#define OPCODE_LDRX_REG_LSL3 (0xf8607800) -#define OPCODE_LDR_REG_F32 (0xbc606800) -#define OPCODE_LDR_REG_F64 (0xfc606800) -#define OPCODE_LDR_REG_F64_S (0xfc607800) -#define OPCODE_LSL (0x1ac02000) -#define OPCODE_LSR (0x1ac02400) -#define OPCODE_MSR_FPCR (0xd51b4400) -#define OPCODE_MUL_V4H (0x0e609c00) -#define OPCODE_NOP (0xd503201f) -#define OPCODE_ORR_V (0x0ea01c00) -#define OPCODE_RET (0xd65f0000) -#define OPCODE_ROR (0x1ac02c00) -#define OPCODE_SADDLP_V2S_4H (0x0e602800) -#define OPCODE_SCVTF_D_Q (0x9e620000) -#define OPCODE_SCVTF_D_W (0x1e620000) -#define OPCODE_SCVTF_V2S (0x0e21d800) -#define OPCODE_SQADD_V8B (0x0e200c00) -#define OPCODE_SQADD_V4H (0x0e600c00) -#define OPCODE_SQSUB_V8B (0x0e202c00) -#define OPCODE_SQSUB_V4H (0x0e602c00) -#define OPCODE_SQXTN_V8B_8H (0x0e214800) -#define OPCODE_SQXTN_V4H_4S (0x0e614800) -#define OPCODE_SHL_VD (0x0f005400) -#define OPCODE_SHL_VQ (0x4f005400) -#define OPCODE_SHRN (0x0f008400) -#define OPCODE_SMULL_V4S_4H (0x0e60c000) -#define OPCODE_SSHR_VD (0x0f000400) -#define OPCODE_SSHR_VQ (0x4f000400) -#define OPCODE_STR_REG (0xb8206800) -#define OPCODE_STRB_REG (0x38206800) -#define OPCODE_STRH_REG (0x78206800) -#define OPCODE_STR_REG_F32 (0xbc206800) -#define OPCODE_STR_REG_F64 (0xfc206800) -#define OPCODE_STR_REG_F64_S (0xfc207800) -#define OPCODE_SUB_V8B (0x2e208400) -#define OPCODE_SUB_V4H (0x2e608400) -#define OPCODE_SUB_V2S (0x2ea08400) -#define OPCODE_UQADD_V8B (0x2e200c00) -#define OPCODE_UQADD_V4H (0x2e600c00) -#define OPCODE_UQSUB_V8B (0x2e202c00) -#define OPCODE_UQSUB_V4H (0x2e602c00) -#define OPCODE_UQXTN_V8B_8H (0x2e214800) -#define OPCODE_UQXTN_V4H_4S (0x2e614800) -#define OPCODE_USHR_VD (0x2f000400) -#define OPCODE_USHR_VQ (0x6f000400) -#define OPCODE_ZIP1_V8B (0x0e003800) -#define OPCODE_ZIP1_V4H (0x0e403800) -#define OPCODE_ZIP1_V2S (0x0e803800) -#define OPCODE_ZIP2_V8B (0x0e007800) -#define OPCODE_ZIP2_V4H (0x0e407800) -#define OPCODE_ZIP2_V2S (0x0e807800) +# define DATPROC_SHIFT(sh) (sh << 10) +# define DATPROC_IMM_SHIFT(sh) (sh << 22) +# define MOV_WIDE_HW(hw) (hw << 21) -#define DATPROC_SHIFT(sh) (sh << 10) -#define DATPROC_IMM_SHIFT(sh) (sh << 22) -#define MOV_WIDE_HW(hw) (hw << 21) +# define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) +# define IMM12(imm_data) ((imm_data) << 10) +# define IMM16(imm_data) ((imm_data) << 5) -#define IMM7_X(imm_data) (((imm_data >> 3) & 0x7f) << 15) -#define IMM12(imm_data) ((imm_data) << 10) -#define IMM16(imm_data) ((imm_data) << 5) +# define IMMN(immn) ((immn) << 22) +# define IMMR(immr) ((immr) << 16) +# define IMMS(imms) ((imms) << 10) -#define IMMN(immn) ((immn) << 22) -#define IMMR(immr) ((immr) << 16) -#define IMMS(imms) ((imms) << 10) +# define IMM_LOGICAL(imm) ((imm) << 10) -#define IMM_LOGICAL(imm) ((imm) << 10) +# define BIT_TBxZ(bit) ((((bit) &0x1f) << 19) | (((bit) &0x20) ? (1 << 31) : 0)) -#define BIT_TBxZ(bit) ((((bit) & 0x1f) << 19) | (((bit) & 0x20) ? (1 << 31) : 0)) +# define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) +# define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) +# define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) &0x1fffff) >> 2) << 5)) +# define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) -#define OFFSET14(offset) (((offset >> 2) << 5) & 0x0007ffe0) -#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -#define OFFSET20(offset) (((offset & 3) << 29) | ((((offset) & 0x1fffff) >> 2) << 5)) -#define OFFSET26(offset) ((offset >> 2) & 0x03ffffff) +# define OFFSET12_B(offset) (offset << 10) +# define OFFSET12_H(offset) ((offset >> 1) << 10) +# define OFFSET12_W(offset) ((offset >> 2) << 10) +# define OFFSET12_Q(offset) ((offset >> 3) << 10) -#define OFFSET12_B(offset) (offset << 10) -#define OFFSET12_H(offset) ((offset >> 1) << 10) -#define OFFSET12_W(offset) ((offset >> 2) << 10) -#define OFFSET12_Q(offset) ((offset >> 3) << 10) +# define SHIFT_IMM_V4H(shift) (((shift) | 0x10) << 16) +# define SHIFT_IMM_V2S(shift) (((shift) | 0x20) << 16) +# define SHIFT_IMM_V2D(shift) (((shift) | 0x40) << 16) -#define SHIFT_IMM_V4H(shift) (((shift) | 0x10) << 16) -#define SHIFT_IMM_V2S(shift) (((shift) | 0x20) << 16) -#define SHIFT_IMM_V2D(shift) (((shift) | 0x40) << 16) +# define SHRN_SHIFT_IMM_V4S(shift) (((shift) | 0x10) << 16) -#define SHRN_SHIFT_IMM_V4S(shift) (((shift) | 0x10) << 16) - -#define DUP_ELEMENT(element) ((element) << 19) +# define DUP_ELEMENT(element) ((element) << 19) /*Returns true if offset fits into 19 bits*/ -static int offset_is_19bit(int offset) +static int +offset_is_19bit(int offset) { - if (offset >= (1 << (18+2))) - return 0; - if (offset < -(1 << (18+2))) - return 0; - return 1; + if (offset >= (1 << (18 + 2))) + return 0; + if (offset < -(1 << (18 + 2))) + return 0; + return 1; } /*Returns true if offset fits into 26 bits*/ -static int offset_is_26bit(int offset) +static int +offset_is_26bit(int offset) { - if (offset >= (1 << (25+2))) - return 0; - if (offset < -(1 << (25+2))) - return 0; - return 1; + if (offset >= (1 << (25 + 2))) + return 0; + if (offset < -(1 << (25 + 2))) + return 0; + return 1; } -static inline int imm_is_imm16(uint32_t imm_data) +static inline int +imm_is_imm16(uint32_t imm_data) { - if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) - return 1; - return 0; + if (!(imm_data & 0xffff0000) || !(imm_data & 0x0000ffff)) + return 1; + return 0; } static void codegen_allocate_new_block(codeblock_t *block); -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static void codegen_allocate_new_block(codeblock_t *block) +static void +codegen_allocate_new_block(codeblock_t *block) { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - uint32_t offset = (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]; + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = (uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos]; - if (!offset_is_26bit(offset)) - fatal("codegen_allocate_new_block - offset out of range %x\n", offset); - /*Add a jump instruction to the new block*/ - *(uint32_t *)&block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); + if (!offset_is_26bit(offset)) + fatal("codegen_allocate_new_block - offset out of range %x\n", offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *) &block_write_data[block_pos] = OPCODE_B | OFFSET26(offset); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -void codegen_alloc(codeblock_t *block, int size) +void +codegen_alloc(codeblock_t *block, int size) { - if (block_pos >= (BLOCK_MAX-size)) - codegen_allocate_new_block(block); + if (block_pos >= (BLOCK_MAX - size)) + codegen_allocate_new_block(block); } -void host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_ADD_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t) imm_data < 0 && imm_data != 0x80000000) { + host_arm64_SUB_IMM(block, dst_reg, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xff000000)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) +void +host_arm64_ADDX_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint64_t imm_data) { - if (!(imm_data & ~0xffffffull)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - fatal("ADD_IMM_X %016llx\n", imm_data); + if (!(imm_data & ~0xffffffull)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_ADDX_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else + fatal("ADD_IMM_X %016llx\n", imm_data); } -void host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_ADD_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ADD_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ADDP_V4S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ADDP_V4S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) +void +host_arm64_ADR(codeblock_t *block, int dst_reg, int offset) { - codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); + codegen_addlong(block, OPCODE_ADR | Rd(dst_reg) | OFFSET20(offset)); } -void host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_AND_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_AND_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_AND_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_AND_REG_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_AND_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_AND_REG_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_AND_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_AND_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_AND_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_ANDS_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_ANDS_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ANDS_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_ASR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_ASR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_B(codeblock_t *block, void *dest) +void +host_arm64_B(codeblock_t *block, void *dest) { - int offset; + int offset; - codegen_alloc(block, 4); - offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; + codegen_alloc(block, 4); + offset = (uintptr_t) dest - (uintptr_t) &block_write_data[block_pos]; - if (!offset_is_26bit(offset)) - fatal("host_arm64_B - offset out of range %x\n", offset); - codegen_addlong(block, OPCODE_B | OFFSET26(offset)); + if (!offset_is_26bit(offset)) + fatal("host_arm64_B - offset out of range %x\n", offset); + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); } -void host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm64_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width-1) & 31)); + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR((32 - lsb) & 31) | IMMS((width - 1) & 31)); } -void host_arm64_BLR(codeblock_t *block, int addr_reg) +void +host_arm64_BLR(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); + codegen_addlong(block, OPCODE_BLR | Rn(addr_reg)); } -uint32_t *host_arm64_BCC_(codeblock_t *block) +uint32_t * +host_arm64_BCC_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BCS_(codeblock_t *block) +uint32_t * +host_arm64_BCS_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_CC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BEQ_(codeblock_t *block) +uint32_t * +host_arm64_BEQ_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_NE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BGE_(codeblock_t *block) +uint32_t * +host_arm64_BGE_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BGT_(codeblock_t *block) +uint32_t * +host_arm64_BGT_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BHI_(codeblock_t *block) +uint32_t * +host_arm64_BHI_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_LS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BLE_(codeblock_t *block) +uint32_t * +host_arm64_BLE_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GT | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BLS_(codeblock_t *block) +uint32_t * +host_arm64_BLS_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_HI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BLT_(codeblock_t *block) +uint32_t * +host_arm64_BLT_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_GE | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BMI_(codeblock_t *block) +uint32_t * +host_arm64_BMI_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_PL | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BNE_(codeblock_t *block) +uint32_t * +host_arm64_BNE_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_EQ | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BPL_(codeblock_t *block) +uint32_t * +host_arm64_BPL_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_MI | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BVC_(codeblock_t *block) +uint32_t * +host_arm64_BVC_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VS | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm64_BVS_(codeblock_t *block) +uint32_t * +host_arm64_BVS_(codeblock_t *block) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_BCOND | COND_VC | OFFSET19(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -void host_arm64_branch_set_offset(uint32_t *opcode, void *dest) +void +host_arm64_branch_set_offset(uint32_t *opcode, void *dest) { - int offset = (uintptr_t)dest - (uintptr_t)opcode; - *opcode |= OFFSET26(offset); + int offset = (uintptr_t) dest - (uintptr_t) opcode; + *opcode |= OFFSET26(offset); } -void host_arm64_BR(codeblock_t *block, int addr_reg) +void +host_arm64_BR(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); + codegen_addlong(block, OPCODE_BR | Rn(addr_reg)); } -void host_arm64_BEQ(codeblock_t *block, void *dest) +void +host_arm64_BEQ(codeblock_t *block, void *dest) { - uint32_t *opcode = host_arm64_BEQ_(block); - host_arm64_branch_set_offset(opcode, dest); + uint32_t *opcode = host_arm64_BEQ_(block); + host_arm64_branch_set_offset(opcode, dest); } -void host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_BIC_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_BIC_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) +void +host_arm64_CBNZ(codeblock_t *block, int reg, uintptr_t dest) { - int offset; + int offset; - codegen_alloc(block, 4); - offset = dest - (uintptr_t)&block_write_data[block_pos]; - if (offset_is_19bit(offset)) - { - codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); - } - else - { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); - offset = (uintptr_t)dest - (uintptr_t)&block_write_data[block_pos]; - codegen_addlong(block, OPCODE_B | OFFSET26(offset)); - } + codegen_alloc(block, 4); + offset = dest - (uintptr_t) &block_write_data[block_pos]; + if (offset_is_19bit(offset)) { + codegen_addlong(block, OPCODE_CBNZ | OFFSET19(offset) | Rt(reg)); + } else { + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_CBZ | OFFSET19(8) | Rt(reg)); + offset = (uintptr_t) dest - (uintptr_t) &block_write_data[block_pos]; + codegen_addlong(block, OPCODE_B | OFFSET26(offset)); + } } -void host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMEQ_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMEQ_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMEQ_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMEQ_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMGT_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMGT_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMGT_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMGT_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) +void +host_arm64_CMN_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) - { - host_arm64_CMP_IMM(block, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xfffff000)) - { - codegen_addlong(block, OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMN_IMM %08x\n", imm_data); + if ((int32_t) imm_data < 0 && imm_data != (1ull << 31)) { + host_arm64_CMP_IMM(block, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xfffff000)) { + codegen_addlong(block, OPCODE_CMN_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMN_IMM %08x\n", imm_data); } -void host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) +void +host_arm64_CMNX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) { - if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) - { - host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t)imm_data); - } - else if (!(imm_data & 0xfffffffffffff000ull)) - { - codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMNX_IMM %08x\n", imm_data); + if ((int64_t) imm_data < 0 && imm_data != (1ull << 63)) { + host_arm64_CMPX_IMM(block, src_n_reg, -(int64_t) imm_data); + } else if (!(imm_data & 0xfffffffffffff000ull)) { + codegen_addlong(block, OPCODE_CMNX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMNX_IMM %08x\n", imm_data); } -void host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) +void +host_arm64_CMP_IMM(codeblock_t *block, int src_n_reg, uint32_t imm_data) { - if ((int32_t)imm_data < 0 && imm_data != (1ull << 31)) - { - host_arm64_CMN_IMM(block, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xfffff000)) - { - codegen_addlong(block, OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMP_IMM %08x\n", imm_data); + if ((int32_t) imm_data < 0 && imm_data != (1ull << 31)) { + host_arm64_CMN_IMM(block, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xfffff000)) { + codegen_addlong(block, OPCODE_CMP_IMM | Rd(REG_WZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMP_IMM %08x\n", imm_data); } -void host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) +void +host_arm64_CMPX_IMM(codeblock_t *block, int src_n_reg, uint64_t imm_data) { - if ((int64_t)imm_data < 0 && imm_data != (1ull << 63)) - { - host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t)imm_data); - } - else if (!(imm_data & 0xfffffffffffff000ull)) - { - codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - } - else - fatal("CMPX_IMM %08x\n", imm_data); + if ((int64_t) imm_data < 0 && imm_data != (1ull << 63)) { + host_arm64_CMNX_IMM(block, src_n_reg, -(int64_t) imm_data); + } else if (!(imm_data & 0xfffffffffffff000ull)) { + codegen_addlong(block, OPCODE_CMPX_IMM | Rd(REG_XZR) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + } else + fatal("CMPX_IMM %08x\n", imm_data); } -void host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_CMP_REG_LSL(codeblock_t *block, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_CMP_LSL | Rd(0x1f) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CSEL_CC(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_CC) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CSEL_EQ(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_EQ) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_CSEL_VS(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_CSEL | CSEL_COND(COND_VS) | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) +void +host_arm64_DUP_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int element) { - codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); + codegen_addlong(block, OPCODE_DUP_V2S | Rd(dst_reg) | Rn(src_n_reg) | DUP_ELEMENT(element)); } -void host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_EOR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_EOR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_EOR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_EOR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_EOR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FABS_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FABS_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FADD_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FADD_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FADD_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FADD_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FCMEQ_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMEQ_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FCMGE_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMGE_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FCMGT_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMGT_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) +void +host_arm64_FCMP_D(codeblock_t *block, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FCMP_D | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVT_D_S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVT_D_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVT_S_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVT_S_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTMS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTMS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTMS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTMS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTNS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTNS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTNS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTNS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTPS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTPS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTPS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTPS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTZS_W_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTZS_W_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTZS_X_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTZS_X_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FCVTZS_V2S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FCVTZS_V2S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FDIV_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FDIV_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FDIV_S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FDIV_S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMAX_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMAX_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMIN_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMIN_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMUL_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMUL_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FMUL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FMUL_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FSUB_D(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FSUB_D | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_FSUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_FSUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_D_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_D_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_D_Q(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_D_Q | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_Q_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_Q_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_S_W(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_S_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FMOV_W_S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FMOV_W_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) +void +host_arm64_FMOV_S_ONE(codeblock_t *block, int dst_reg) { - codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); + codegen_addlong(block, OPCODE_FMOV_S_ONE | Rd(dst_reg)); } -void host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FNEG_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FNEG_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FRINTX_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FRINTX_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FSQRT_D(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FSQRT_D | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_FSQRT_S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_FSQRT_S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +void +host_arm64_LDP_POSTIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { - if (!in_range7_x(offset)) - fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); + if (!in_range7_x(offset)) + fatal("host_arm64_LDP_POSTIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_LDP_POSTIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } -void host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_w(offset)) - fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_w(offset)) + fatal("host_arm64_LDR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDR_IMM_X(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_q(offset)) - fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_q(offset)) + fatal("host_arm64_LDR_IMM_X out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDR_IMM_X | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_X(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRX_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_F32(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDR_IMM_F64(codeblock_t *block, int dest_reg, int base_reg, int offset) { - codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_F64(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDR_REG_F64_S(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDRB_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_b(offset)) - fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_b(offset)) + fatal("host_arm64_LDRB_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRB_IMM_W | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDRB_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_LDRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_h(offset)) - fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_h(offset)) + fatal("host_arm64_LDRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_LDRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDRH_REG(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) +void +host_arm64_LDRX_REG_LSL3(codeblock_t *block, int dest_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); + codegen_addlong(block, OPCODE_LDRX_REG_LSL3 | Rn(base_reg) | Rm(offset_reg) | Rt(dest_reg)); } -void host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_LSL(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_ASR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - if (dst_reg != src_m_reg || shift) - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + if (dst_reg != src_m_reg || shift) + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_LSR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_ROR | Rd(dst_reg) | Rn(REG_WZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) +void +host_arm64_MOVX_IMM(codeblock_t *block, int reg, uint64_t imm_data) { - codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); - if ((imm_data >> 16) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); - if ((imm_data >> 32) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); - if ((imm_data >> 48) & 0xffff) - codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVZ_X | MOV_WIDE_HW(0) | IMM16(imm_data & 0xffff) | Rd(reg)); + if ((imm_data >> 16) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(1) | IMM16((imm_data >> 16) & 0xffff) | Rd(reg)); + if ((imm_data >> 32) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(2) | IMM16((imm_data >> 32) & 0xffff) | Rd(reg)); + if ((imm_data >> 48) & 0xffff) + codegen_addlong(block, OPCODE_MOVK_X | MOV_WIDE_HW(3) | IMM16((imm_data >> 48) & 0xffff) | Rd(reg)); } -void host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) +void +host_arm64_MOVX_REG(codeblock_t *block, int dst_reg, int src_m_reg, int shift) { - if (dst_reg != src_m_reg) - codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + if (dst_reg != src_m_reg) + codegen_addlong(block, OPCODE_ORRX_LSL | Rd(dst_reg) | Rn(REG_XZR) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) +void +host_arm64_MOVZ_IMM(codeblock_t *block, int reg, uint32_t imm_data) { - int hw; + int hw; - if (!imm_is_imm16(imm_data)) - fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); + if (!imm_is_imm16(imm_data)) + fatal("MOVZ_IMM - imm not representable %08x\n", imm_data); - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; - codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVZ_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } -void host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) +void +host_arm64_MOVK_IMM(codeblock_t *block, int reg, uint32_t imm_data) { - int hw; + int hw; - if (!imm_is_imm16(imm_data)) - fatal("MOVK_IMM - imm not representable %08x\n", imm_data); + if (!imm_is_imm16(imm_data)) + fatal("MOVK_IMM - imm not representable %08x\n", imm_data); - hw = (imm_data & 0xffff0000) ? 1 : 0; - if (hw) - imm_data >>= 16; + hw = (imm_data & 0xffff0000) ? 1 : 0; + if (hw) + imm_data >>= 16; - codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); + codegen_addlong(block, OPCODE_MOVK_W | MOV_WIDE_HW(hw) | IMM16(imm_data) | Rd(reg)); } -void host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) +void +host_arm64_MSR_FPCR(codeblock_t *block, int src_reg) { - codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); + codegen_addlong(block, OPCODE_MSR_FPCR | Rd(src_reg)); } -void host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_MUL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_MUL_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_NOP(codeblock_t *block) +void +host_arm64_NOP(codeblock_t *block) { - codegen_addlong(block, OPCODE_NOP); + codegen_addlong(block, OPCODE_NOP); } -void host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_ORR_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - uint32_t imm_encoding = host_arm64_find_imm(imm_data); + uint32_t imm_encoding = host_arm64_find_imm(imm_data); - if (imm_encoding) - { - codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); - } - else - { - host_arm64_mov_imm(block, REG_W16, imm_data); - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (imm_encoding) { + codegen_addlong(block, OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM_LOGICAL(imm_encoding)); + } else { + host_arm64_mov_imm(block, REG_W16, imm_data); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_ORR_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_ORR_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ORR_REG_V(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ORR_V | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_RET(codeblock_t *block, int reg) +void +host_arm64_RET(codeblock_t *block, int reg) { - codegen_addlong(block, OPCODE_RET | Rn(reg)); + codegen_addlong(block, OPCODE_RET | Rn(reg)); } -void host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) +void +host_arm64_ROR(codeblock_t *block, int dst_reg, int src_n_reg, int shift_reg) { - codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); + codegen_addlong(block, OPCODE_ROR | Rd(dst_reg) | Rn(src_n_reg) | Rm(shift_reg)); } -void host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) +void +host_arm64_SADDLP_V2S_4H(codeblock_t *block, int dst_reg, int src_n_reg) { - codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); + codegen_addlong(block, OPCODE_SADDLP_V2S_4H | Rd(dst_reg) | Rn(src_n_reg)); } -void host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm64_SBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); + codegen_addlong(block, OPCODE_SBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb + width - 1) & 31)); } -void host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SCVTF_D_Q(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SCVTF_D_Q | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SCVTF_D_W(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SCVTF_D_W | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SCVTF_V2S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SCVTF_V2S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHRN_V4H_4S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 16) - fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); - codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16-shift)); + if (shift > 16) + fatal("host_arm64_SHRN_V4H_4S : shift > 16\n"); + codegen_addlong(block, OPCODE_SHRN | Rd(dst_reg) | Rn(src_n_reg) | SHRN_SHIFT_IMM_V4S(16 - shift)); } -void host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SMULL_V4S_4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SMULL_V4S_4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_SQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_SQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHL_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(shift)); } -void host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHL_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); + codegen_addlong(block, OPCODE_SHL_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(shift)); } -void host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SHL_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); + codegen_addlong(block, OPCODE_SHL_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(shift)); } -void host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SSHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 16) - fatal("host_arm_USHR_V4H : shift > 16\n"); - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16 - shift)); } -void host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SSHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 32) - fatal("host_arm_SSHR_V2S : shift > 32\n"); - codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); + if (shift > 32) + fatal("host_arm_SSHR_V2S : shift > 32\n"); + codegen_addlong(block, OPCODE_SSHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32 - shift)); } -void host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_SSHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 64) - fatal("host_arm_SSHR_V2D : shift > 64\n"); - codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); + if (shift > 64) + fatal("host_arm_SSHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_SSHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64 - shift)); } -void host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) +void +host_arm64_STP_PREIDX_X(codeblock_t *block, int src_reg1, int src_reg2, int base_reg, int offset) { - if (!in_range7_x(offset)) - fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); - codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); + if (!in_range7_x(offset)) + fatal("host_arm64_STP_PREIDX out of range7 %i\n", offset); + codegen_addlong(block, OPCODE_STP_PREIDX_X | IMM7_X(offset) | Rn(base_reg) | Rt(src_reg1) | Rt2(src_reg2)); } -void host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STR_IMM_W(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_w(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_w(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_W | OFFSET12_W(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STR_IMM_Q(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_q(offset)) - fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_q(offset)) + fatal("host_arm64_STR_IMM_W out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STR_IMM_Q | OFFSET12_Q(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG_F32(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG_F32 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) +void +host_arm64_STR_IMM_F64(codeblock_t *block, int src_reg, int base_reg, int offset) { - codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_IMM_F64 | OFFSET12_Q(offset) | Rn(base_reg) | Rt(src_reg)); } -void host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG_F64(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG_F64 | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STR_REG_F64_S(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STR_REG_F64_S | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STRB_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_b(offset)) - fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_b(offset)) + fatal("host_arm64_STRB_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRB_IMM | OFFSET12_B(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STRB_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STRB_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm64_STRH_IMM(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if (!in_range12_h(offset)) - fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); - codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); + if (!in_range12_h(offset)) + fatal("host_arm64_STRH_IMM out of range12 %i\n", offset); + codegen_addlong(block, OPCODE_STRH_IMM | OFFSET12_H(offset) | Rn(base_reg) | Rt(dest_reg)); } -void host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) +void +host_arm64_STRH_REG(codeblock_t *block, int src_reg, int base_reg, int offset_reg) { - codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); + codegen_addlong(block, OPCODE_STRH_REG | Rn(base_reg) | Rm(offset_reg) | Rt(src_reg)); } -void host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) +void +host_arm64_SUB_IMM(codeblock_t *block, int dst_reg, int src_n_reg, uint32_t imm_data) { - if (!imm_data) - host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); - else if ((int32_t)imm_data < 0 && imm_data != 0x80000000) - { - host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t)imm_data); - } - else if (!(imm_data & 0xff000000)) - { - if (imm_data & 0xfff) - { - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); - if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else if (imm_data & 0xfff000) - codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); - } - else - { - host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); - } + if (!imm_data) + host_arm64_MOV_REG(block, dst_reg, src_n_reg, 0); + else if ((int32_t) imm_data < 0 && imm_data != 0x80000000) { + host_arm64_ADD_IMM(block, dst_reg, src_n_reg, -(int32_t) imm_data); + } else if (!(imm_data & 0xff000000)) { + if (imm_data & 0xfff) { + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12(imm_data & 0xfff) | DATPROC_IMM_SHIFT(0)); + if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(dst_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else if (imm_data & 0xfff000) + codegen_addlong(block, OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_n_reg) | IMM12((imm_data >> 12) & 0xfff) | DATPROC_IMM_SHIFT(1)); + } else { + host_arm64_MOVZ_IMM(block, REG_W16, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, REG_W16, imm_data & 0xffff0000); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(REG_W16) | DATPROC_SHIFT(0)); + } } -void host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_SUB_REG(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_LSL | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) +void +host_arm64_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg, int shift) { - codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); + codegen_addlong(block, OPCODE_SUB_LSR | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg) | DATPROC_SHIFT(shift)); } -void host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_SUB_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_SUB_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -uint32_t *host_arm64_TBNZ(codeblock_t *block, int reg, int bit) +uint32_t * +host_arm64_TBNZ(codeblock_t *block, int reg, int bit) { - codegen_alloc(block, 12); - codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); - codegen_addlong(block, OPCODE_B); - return (uint32_t *)&block_write_data[block_pos-4]; + codegen_alloc(block, 12); + codegen_addlong(block, OPCODE_TBZ | Rt(reg) | BIT_TBxZ(bit) | OFFSET14(8)); + codegen_addlong(block, OPCODE_B); + return (uint32_t *) &block_write_data[block_pos - 4]; } -void host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm64_UBFX(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb+width-1) & 31)); + codegen_addlong(block, OPCODE_UBFX | Rd(dst_reg) | Rn(src_reg) | IMMN(0) | IMMR(lsb) | IMMS((lsb + width - 1) & 31)); } -void host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQADD_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQADD_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQADD_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQADD_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQSUB_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQSUB_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_UQSUB_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_UQSUB_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_UQXTN_V8B_8H(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_UQXTN_V8B_8H | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm64_UQXTN_V4H_4S(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); + codegen_addlong(block, OPCODE_UQXTN_V4H_4S | Rd(dst_reg) | Rn(src_reg)); } -void host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_USHR_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 16) - fatal("host_arm_USHR_V4H : shift > 16\n"); - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16-shift)); + if (shift > 16) + fatal("host_arm_USHR_V4H : shift > 16\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V4H(16 - shift)); } -void host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_USHR_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 32) - fatal("host_arm_USHR_V4S : shift > 32\n"); - codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32-shift)); + if (shift > 32) + fatal("host_arm_USHR_V4S : shift > 32\n"); + codegen_addlong(block, OPCODE_USHR_VD | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2S(32 - shift)); } -void host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) +void +host_arm64_USHR_V2D(codeblock_t *block, int dst_reg, int src_n_reg, int shift) { - if (shift > 64) - fatal("host_arm_USHR_V2D : shift > 64\n"); - codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64-shift)); + if (shift > 64) + fatal("host_arm_USHR_V2D : shift > 64\n"); + codegen_addlong(block, OPCODE_USHR_VQ | Rd(dst_reg) | Rn(src_n_reg) | SHIFT_IMM_V2D(64 - shift)); } -void host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP1_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP1_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP1_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP1_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP1_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP1_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP2_V8B(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP2_V8B | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP2_V4H(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP2_V4H | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) +void +host_arm64_ZIP2_V2S(codeblock_t *block, int dst_reg, int src_n_reg, int src_m_reg) { - codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); + codegen_addlong(block, OPCODE_ZIP2_V2S | Rd(dst_reg) | Rn(src_n_reg) | Rm(src_m_reg)); } -void host_arm64_call(codeblock_t *block, void *dst_addr) +void +host_arm64_call(codeblock_t *block, void *dst_addr) { - host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); - host_arm64_BLR(block, REG_X16); + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t) dst_addr); + host_arm64_BLR(block, REG_X16); } -void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) +void +host_arm64_jump(codeblock_t *block, uintptr_t dst_addr) { - host_arm64_MOVX_IMM(block, REG_X16, (uint64_t)dst_addr); - host_arm64_BR(block, REG_X16); + host_arm64_MOVX_IMM(block, REG_X16, (uint64_t) dst_addr); + host_arm64_BR(block, REG_X16); } -void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) +void +host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data) { - if (imm_is_imm16(imm_data)) - host_arm64_MOVZ_IMM(block, reg, imm_data); - else - { - host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); - host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); - } + if (imm_is_imm16(imm_data)) + host_arm64_MOVZ_IMM(block, reg, imm_data); + else { + host_arm64_MOVZ_IMM(block, reg, imm_data & 0xffff); + host_arm64_MOVK_IMM(block, reg, imm_data & 0xffff0000); + } } #endif diff --git a/src/codegen_new/codegen_backend_arm64_ops.h b/src/codegen_new/codegen_backend_arm64_ops.h index c89a02311..df751b4aa 100644 --- a/src/codegen_new/codegen_backend_arm64_ops.h +++ b/src/codegen_new/codegen_backend_arm64_ops.h @@ -251,13 +251,11 @@ void host_arm64_call(codeblock_t *block, void *dst_addr); void host_arm64_jump(codeblock_t *block, uintptr_t dst_addr); void host_arm64_mov_imm(codeblock_t *block, int reg, uint32_t imm_data); - -#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) & 7)) +#define in_range7_x(offset) (((offset) >= -0x200) && ((offset) < (0x200)) && !((offset) &7)) #define in_range12_b(offset) (((offset) >= 0) && ((offset) < 0x1000)) -#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) & 1)) -#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) & 3)) -#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) & 7)) - +#define in_range12_h(offset) (((offset) >= 0) && ((offset) < 0x2000) && !((offset) &1)) +#define in_range12_w(offset) (((offset) >= 0) && ((offset) < 0x4000) && !((offset) &3)) +#define in_range12_q(offset) (((offset) >= 0) && ((offset) < 0x8000) && !((offset) &7)) void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); diff --git a/src/codegen_new/codegen_backend_arm64_uops.c b/src/codegen_new/codegen_backend_arm64_uops.c index 10a07a4a2..91fb9c903 100644 --- a/src/codegen_new/codegen_backend_arm64_uops.c +++ b/src/codegen_new/codegen_backend_arm64_uops.c @@ -1,3372 +1,3251 @@ #if defined __aarch64__ || defined _M_ARM64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_backend.h" -#include "codegen_backend_arm64_defs.h" -#include "codegen_backend_arm64_ops.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x87.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_backend.h" +# include "codegen_backend_arm64_defs.h" +# include "codegen_backend_arm64_ops.h" +# include "codegen_ir_defs.h" -#define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) +# define OFFSET19(offset) (((offset >> 2) << 5) & 0x00ffffe0) -#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) +# define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0x1f) -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) +static int +codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); - host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_ADD_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ADD_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_a, 0x0000ff00); + host_arm64_ADD_REG(block, REG_TEMP, REG_TEMP, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ADD_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); - return 0; + host_arm64_ADD_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +static int +codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); - host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); - host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); - host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_AND_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_AND_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff0000); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ASR(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffffff00); + host_arm64_AND_REG_ROR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_b, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_a, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_ORR_IMM(block, REG_TEMP, src_reg_a, 0xffff00ff); + host_arm64_AND_REG_ROR(block, REG_TEMP, src_reg_b, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_AND_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); - } - else - fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } else + fatal("AND_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ANDN(codeblock_t *block, uop_t *uop) +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); - } - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_BIC_REG_V(block, dest_reg, src_reg_b, src_reg_a); + } else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_arm64_call(block, uop->p); + host_arm64_call(block, uop->p); - return 0; + return 0; } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); - host_arm64_call(block, uop->p); - host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm64_call(block, uop->p); + host_arm64_MOV_REG(block, dest_reg, REG_W0, 0); - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_arm64_call(block, uop->p); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); + host_arm64_call(block, uop->p); + host_arm64_CBNZ(block, REG_X0, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm64_BEQ(block, uop->p); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm64_BEQ(block, uop->p); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BNE_(block); + uop->p = host_arm64_BNE_(block); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BEQ_(block); + uop->p = host_arm64_BEQ_(block); - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); - jump_p = host_arm64_BCC_(block); - host_arm64_branch_set_offset(jump_p, uop->p); + jump_p = host_arm64_BCC_(block); + host_arm64_branch_set_offset(jump_p, uop->p); - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); - jump_p = host_arm64_BHI_(block); - host_arm64_branch_set_offset(jump_p, uop->p); + jump_p = host_arm64_BHI_(block); + host_arm64_branch_set_offset(jump_p, uop->p); - return 0; + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BCS_(block); + uop->p = host_arm64_BCS_(block); - return 0; + return 0; } -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BHI_(block); + uop->p = host_arm64_BHI_(block); - return 0; + return 0; } -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BGE_(block); + uop->p = host_arm64_BGE_(block); - return 0; + return 0; } -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BGT_(block); + uop->p = host_arm64_BGT_(block); - return 0; + return 0; } -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BVC_(block); + uop->p = host_arm64_BVC_(block); - return 0; + return 0; } -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BNE_(block); + uop->p = host_arm64_BNE_(block); - return 0; + return 0; } -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BCC_(block); + uop->p = host_arm64_BCC_(block); - return 0; + return 0; } -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BLS_(block); + uop->p = host_arm64_BLS_(block); - return 0; + return 0; } -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BLT_(block); + uop->p = host_arm64_BLT_(block); - return 0; + return 0; } -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BLE_(block); + uop->p = host_arm64_BLE_(block); - return 0; + return 0; } -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BVS_(block); + uop->p = host_arm64_BVS_(block); - return 0; + return 0; } -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); - host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 16); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg_a, 24); + host_arm64_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BEQ_(block); + uop->p = host_arm64_BEQ_(block); - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FABS_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FABS_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FNEG_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FNEG_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FSQRT_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FSQRT_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FTST(codeblock_t *block, uop_t *uop) +static int +codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); - host_arm64_MOVZ_IMM(block, dest_reg, 0); - host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); - host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); - host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); - host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); - } - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_arm64_FSUB_D(block, REG_V_TEMP, REG_V_TEMP, REG_V_TEMP); + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, REG_V_TEMP); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FADD_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FCOM(codeblock_t *block, uop_t *uop) +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_MOVZ_IMM(block, dest_reg, 0); - host_arm64_FCMP_D(block, src_reg_a, src_reg_b); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); - host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); - host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); - host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0|C2|C3); - host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); - host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); - } - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_MOVZ_IMM(block, dest_reg, 0); + host_arm64_FCMP_D(block, src_reg_a, src_reg_b); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C3); + host_arm64_ORR_IMM(block, REG_TEMP2, dest_reg, C0); + host_arm64_CSEL_EQ(block, dest_reg, REG_TEMP, dest_reg); + host_arm64_ORR_IMM(block, REG_TEMP, dest_reg, C0 | C2 | C3); + host_arm64_CSEL_CC(block, dest_reg, REG_TEMP2, dest_reg); + host_arm64_CSEL_VS(block, dest_reg, REG_TEMP, dest_reg); + } else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FDIV(codeblock_t *block, uop_t *uop) +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FMUL(codeblock_t *block, uop_t *uop) +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FSUB(codeblock_t *block, uop_t *uop) +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm64_FSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_ptr; + uint32_t *branch_ptr; - if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) - fatal("codegen_FP_ENTER - out of range\n"); + if (!in_range12_w((uintptr_t) &cr0 - (uintptr_t) &cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm64_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm64_BEQ_(block); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); - host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm64_mov_imm(block, REG_ARG0, 7); - host_arm64_call(block, x86_int); - host_arm64_B(block, codegen_exit_rout); + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, codegen_exit_rout); - host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); + host_arm64_branch_set_offset(branch_ptr, &block_write_data[block_pos]); - return 0; + return 0; } -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_ptr; + uint32_t *branch_ptr; - if (!in_range12_w((uintptr_t)&cr0 - (uintptr_t)&cpu_state)) - fatal("codegen_MMX_ENTER - out of range\n"); + if (!in_range12_w((uintptr_t) &cr0 - (uintptr_t) &cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm64_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm64_BEQ_(block); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm64_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm64_BEQ_(block); - host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm64_mov_imm(block, REG_ARG0, 7); - host_arm64_call(block, x86_int); - host_arm64_B(block, codegen_exit_rout); + host_arm64_mov_imm(block, REG_TEMP, uop->imm_data); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm64_mov_imm(block, REG_ARG0, 7); + host_arm64_call(block, x86_int); + host_arm64_B(block, codegen_exit_rout); - host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); + host_arm64_branch_set_offset(branch_ptr, &block->data[block_pos]); - host_arm64_mov_imm(block, REG_TEMP, 0x01010101); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); - host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); + host_arm64_mov_imm(block, REG_TEMP, 0x01010101); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); + host_arm64_STR_IMM_W(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); + host_arm64_STR_IMM_W(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm64_STRB_IMM(block, REG_WZR, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); - return 0; + return 0; } -static int codegen_JMP(codeblock_t *block, uop_t *uop) +static int +codegen_JMP(codeblock_t *block, uop_t *uop) { - host_arm64_jump(block, (uintptr_t)uop->p); + host_arm64_jump(block, (uintptr_t) uop->p); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); - } - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + } else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); - return 0; + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; } -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); - return 0; + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; } -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); - return 0; + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; } -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG0, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG1, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG2, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); + host_arm64_mov_imm(block, REG_ARG3, uop->imm_data); - return 0; + return 0; } -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t)uop->p); - host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); - host_arm64_call(block, (void *)loadseg); - host_arm64_CBNZ(block, REG_X0, (uintptr_t)codegen_exit_rout); + host_arm64_MOVX_IMM(block, REG_ARG1, (uint64_t) uop->p); + host_arm64_AND_IMM(block, REG_ARG0, src_reg, 0xffff); + host_arm64_call(block, (void *) loadseg); + host_arm64_CBNZ(block, REG_X0, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm64_call(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_call(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_call(block, codegen_mem_load_long); - } - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); - } + host_arm64_ADD_IMM(block, REG_X0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm64_call(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm64_call(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm64_call(block, codegen_mem_load_long); + } else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } - return 0; + return 0; } -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm64_call(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_call(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_call(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_arm64_call(block, codegen_mem_load_quad); - } - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); - } - else if (REG_IS_Q(dest_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); - } + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm64_call(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm64_call(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm64_call(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_arm64_call(block, codegen_mem_load_quad); + } else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm64_BFI(block, dest_reg, REG_X0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm64_MOV_REG(block, dest_reg, REG_X0, 0); + } else if (REG_IS_Q(dest_size)) { + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + } - return 0; + return 0; } -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_call(block, codegen_mem_load_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + host_arm64_FMOV_D_D(block, dest_reg, REG_V_TEMP); - return 0; + return 0; } -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_call(block, codegen_mem_load_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); + host_arm64_ADD_REG(block, REG_X0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_call(block, codegen_mem_load_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + host_arm64_FCVT_D_S(block, dest_reg, REG_V_TEMP); - return 0; + return 0; } -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); - host_arm64_call(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, REG_W1, src_reg, 0); - host_arm64_call(block, codegen_mem_store_long); - } - else - fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); - host_arm64_call(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); - host_arm64_call(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, REG_W1, src_reg, 0); - host_arm64_call(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_quad); - } - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_ADD_IMM(block, REG_W0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); host_arm64_call(block, codegen_mem_store_byte); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); + } else if (REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); host_arm64_call(block, codegen_mem_store_word); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - host_arm64_mov_imm(block, REG_W1, uop->imm_data); + } else if (REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); host_arm64_call(block, codegen_mem_store_long); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + } else + fatal("MEM_STORE_ABS - %02x\n", uop->dest_reg_a_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - return 0; + return 0; +} +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xff); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_W1, src_reg, 8, 8); + host_arm64_call(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_W1, src_reg, 0xffff); + host_arm64_call(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, REG_W1, src_reg, 0); + host_arm64_call(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_quad); + } else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_byte); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_single); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); - - return 0; + return 0; } -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_word); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); - if (uop->imm_data) - host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_mem_store_double); - host_arm64_CBNZ(block, REG_X1, (uintptr_t)codegen_exit_rout); + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - return 0; + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + host_arm64_mov_imm(block, REG_W1, uop->imm_data); + host_arm64_call(block, codegen_mem_store_long); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_MOV(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) - { - host_arm64_BFI(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - } - else - fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - return 0; + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FCVT_S_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_single); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (REG_IS_L(dest_size)) - { - host_arm64_mov_imm(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); - } - else if (REG_IS_B(dest_size)) - { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("MOV_IMM %x\n", uop->dest_reg_a_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); + host_arm64_ADD_REG(block, REG_W0, seg_reg, addr_reg, 0); + if (uop->imm_data) + host_arm64_ADD_IMM(block, REG_X0, REG_X0, uop->imm_data); + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_mem_store_double); + host_arm64_CBNZ(block, REG_X1, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) +static int +codegen_MOV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) { + host_arm64_BFI(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + } else + fatal("MOV %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_arm64_FMOV_D_Q(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_W_S(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size)) { + host_arm64_mov_imm(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_arm64_MOVK_IMM(block, dest_reg, uop->imm_data & 0xffff); + } else if (REG_IS_B(dest_size)) { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm64_MOVZ_IMM(block, REG_TEMP, uop->imm_data & 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("MOV_IMM %x\n", uop->dest_reg_a_real); - return 0; + return 0; +} +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_arm64_MOVX_IMM(block, uop->dest_reg_a_real, (uint64_t) uop->p); + + return 0; } -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_arm64_SCVTF_D_W(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); - host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); - } + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm64_SBFX(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_arm64_FMOV_D_Q(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_W_S(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xff); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, dest_reg, src_reg, 0xffff); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_arm64_SCVTF_D_W(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_arm64_SBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SCVTF_D_W(block, dest_reg, REG_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + host_arm64_FMOV_Q_D(block, REG_TEMP, src_reg); + host_arm64_SCVTF_D_Q(block, dest_reg, REG_TEMP); + } else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); + branch_offset = host_arm64_TBNZ(block, tag_reg, 7); + + host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); + host_arm64_call(block, codegen_fp_round_quad); + host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); + + host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); + } else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); + host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); + host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); + host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); + } else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); + } else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); + } else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); + host_arm64_FMOV_S_ONE(block, REG_V_TEMP); + host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); + host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); + } else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); + } else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); + host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); + host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round); - host_arm64_MOV_REG(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_arm64_FMOV_D_D(block, dest_reg, src_64_reg); - branch_offset = host_arm64_TBNZ(block, tag_reg, 7); - - host_arm64_FMOV_D_D(block, REG_V_TEMP, src_reg); - host_arm64_call(block, codegen_fp_round_quad); - host_arm64_FMOV_D_Q(block, dest_reg, REG_TEMP); - - host_arm64_branch_set_offset(branch_offset, &block_write_data[block_pos]); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDR_IMM_W(block, dest_reg, REG_TEMP, 0); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDRB_IMM_W(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm64_LDRB_IMM_W(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm64_MOVX_IMM(block, REG_TEMP, (uint64_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm64_LDRH_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm64_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_NOP(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - return 0; -} + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ORR_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_ORR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_ORR_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_ORR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm64_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("OR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_SQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_SQXTN_V4H_4S(block, REG_V_TEMP, src_reg_b); - host_arm64_SQXTN_V4H_4S(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_arm64_UQXTN_V8B_8H(block, REG_V_TEMP, src_reg_b); - host_arm64_UQXTN_V8B_8H(block, dest_reg, dest_reg); - host_arm64_ZIP1_V2S(block, dest_reg, dest_reg, REG_V_TEMP); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm64_FMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PADDB(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDW(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDD(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ADD_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQADD_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQADD_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_CMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) +static int +codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm64_FCVTZS_V2S(block, dest_reg, src_reg_a); - } - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 32); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 16); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + cs = cs; + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_mov_imm(block, REG_TEMP2, 8); + host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PFADD(codeblock_t *block, uop_t *uop) +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FADD_V2S(block, dest_reg, src_reg_a, src_reg_b); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); } - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMEQ_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 16); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16 - (uop->imm_data & 15)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMGE_V2S(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + host_arm64_BFI(block, dest_reg, src_reg, 0, 8); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); } - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FCMGT_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMAX_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMIN_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FMUL_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm64_FMOV_S_ONE(block, REG_V_TEMP); - host_arm64_FDIV_S(block, dest_reg, REG_V_TEMP, src_reg_a); - host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm64_FSQRT_S(block, REG_V_TEMP, src_reg_a); - host_arm64_FMOV_S_ONE(block, REG_V_TEMP); - host_arm64_FDIV_S(block, dest_reg, dest_reg, REG_V_TEMP); - host_arm64_DUP_V2S(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_FSUB_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm64_SCVTF_V2S(block, dest_reg, src_reg_a); - } - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SMULL_V4S_4H(block, REG_V_TEMP, src_reg_a, src_reg_b); - host_arm64_ADDP_V4S(block, dest_reg, REG_V_TEMP, REG_V_TEMP); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SMULL_V4S_4H(block, dest_reg, src_reg_a, src_reg_b); - host_arm64_SHRN_V4H_4S(block, dest_reg, dest_reg, 16); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_MUL_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_SHL_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_SSHR_V4H(block, dest_reg, src_reg, 15); - else - host_arm64_SSHR_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_SSHR_V2S(block, dest_reg, src_reg, 31); - else - host_arm64_SSHR_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_SSHR_V2D(block, dest_reg, src_reg, 63); - else - host_arm64_SSHR_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V4H(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V2S(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm64_FMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm64_EOR_REG_V(block, dest_reg, dest_reg, dest_reg); - else - host_arm64_USHR_V2D(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SUB_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_SQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQSUB_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_UQSUB_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP2_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V8B(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V4H(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_ZIP1_V2S(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 32); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_ROR(block, dest_reg, src_reg, REG_TEMP2); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 16); - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_ROR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - cs = cs; - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 8); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_mov_imm(block, REG_TEMP2, 8); - host_arm64_SUB_REG(block, REG_TEMP2, REG_TEMP2, shift_reg, 0); - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else - { - host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - host_arm64_BFI(block, dest_reg, src_reg, 0, 16); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - host_arm64_BFI(block, dest_reg, src_reg, 0, 8); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR(codeblock_t *block, uop_t *uop) +static int +codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ROR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ROR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm64_MOV_REG(block, dest_reg, src_reg, 0); - } - else - { - host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm64_MOV_REG(block, dest_reg, src_reg, 0); + } else { + host_arm64_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 16); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 0, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_ORR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR(codeblock_t *block, uop_t *uop) +static int +codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_ASR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_ASR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_ASR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); - host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 16, 16); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 24); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, 16); + host_arm64_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_UBFX(block, REG_TEMP, REG_TEMP, 24, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL(codeblock_t *block, uop_t *uop) +static int +codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_LSL(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_LSL(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_LSL(block, REG_TEMP, src_reg, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSL(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_MOV_REG(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR(codeblock_t *block, uop_t *uop) +static int +codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_LSR(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_LSR(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_LSR(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xffff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg, 0xff); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_UBFX(block, REG_TEMP, src_reg, 8, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_W16, uop->imm_data); + host_arm64_mov_imm(block, REG_W16, uop->imm_data); - if (in_range12_w((uintptr_t)uop->p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + if (in_range12_w((uintptr_t) uop->p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_W(block, REG_W16, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { - host_arm64_mov_imm(block, REG_W16, uop->imm_data); + host_arm64_mov_imm(block, REG_W16, uop->imm_data); - if (in_range12_b((uintptr_t)uop->p - (uintptr_t)&cpu_state)) - host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + if (in_range12_b((uintptr_t) uop->p - (uintptr_t) &cpu_state)) + host_arm64_STRB_IMM(block, REG_W16, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_SUB(codeblock_t *block, uop_t *uop) +static int +codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_SUB_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm64_SUB_REG(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm64_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm64_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm64_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm64_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm64_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BEQ_(block); + uop->p = host_arm64_BEQ_(block); - return 0; + return 0; } -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm64_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm64_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm64_BNE_(block); + uop->p = host_arm64_BNE_(block); - return 0; + return 0; } -static int codegen_XOR(codeblock_t *block, uop_t *uop) +static int +codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); - host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm64_EOR_REG_V(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm64_EOR_REG(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xffff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm64_AND_IMM(block, REG_TEMP, src_reg_b, 0xff); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm64_UBFX(block, REG_TEMP, src_reg_b, 8, 8); + host_arm64_EOR_REG(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm64_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("XOR_IMM %x %x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, - [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP & + UOP_MASK] + = codegen_JMP, - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_8 - not in range\n"); + if (in_range12_b((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDRB_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_16 - not in range\n"); + if (in_range12_h((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_16 - not in range\n"); } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (in_range12_w((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_pointer - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_X(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_pointer - not in range\n"); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_LDR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_double - not in range\n"); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_LDR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - if (in_range12_b((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_8 - not in range\n"); + if (in_range12_b((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - if (in_range12_h((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_16 - not in range\n"); + if (in_range12_h((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_16 - not in range\n"); } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - if (in_range12_w((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_32 - not in range\n"); + if (in_range12_w((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_W(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_double - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_F64(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_double - not in range\n"); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STRB_REG(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); - host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t)base - (uintptr_t)&cpu_state); - host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); + host_arm64_LDR_IMM_W(block, REG_TEMP, REG_XSP, IREG_TOP_diff_stack_offset); + host_arm64_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm64_ADDX_IMM(block, REG_TEMP2, REG_CPUSTATE, (uintptr_t) base - (uintptr_t) &cpu_state); + host_arm64_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm64_STR_REG_F64_S(block, host_reg, REG_TEMP2, REG_TEMP); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - if (in_range12_q((uintptr_t)p - (uintptr_t)&cpu_state)) - host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_ptr - not in range\n"); + if (in_range12_q((uintptr_t) p - (uintptr_t) &cpu_state)) + host_arm64_STR_IMM_Q(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (in_range12_h(stack_offset)) - host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_32_stack - not in range\n"); + if (in_range12_h(stack_offset)) + host_arm64_LDRH_IMM(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (in_range12_w(stack_offset)) - host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_32_stack - not in range\n"); + if (in_range12_w(stack_offset)) + host_arm64_LDR_IMM_W(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_32_stack - not in range\n"); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (in_range12_q(stack_offset)) - host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_read_pointer_stack - not in range\n"); + if (in_range12_q(stack_offset)) + host_arm64_LDR_IMM_X(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_read_pointer_stack - not in range\n"); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_LDR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - if (in_range12_w(stack_offset)) - host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); - else - fatal("codegen_direct_write_32_stack - not in range\n"); + if (in_range12_w(stack_offset)) + host_arm64_STR_IMM_W(block, host_reg, REG_XSP, stack_offset); + else + fatal("codegen_direct_write_32_stack - not in range\n"); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); + host_arm64_STR_IMM_F64(block, host_reg, REG_XSP, stack_offset); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - host_arm64_branch_set_offset(p, &block_write_data[block_pos]); + host_arm64_branch_set_offset(p, &block_write_data[block_pos]); } #endif diff --git a/src/codegen_new/codegen_backend_arm_defs.h b/src/codegen_new/codegen_backend_arm_defs.h index 74567998a..745854429 100644 --- a/src/codegen_new/codegen_backend_arm_defs.h +++ b/src/codegen_new/codegen_backend_arm_defs.h @@ -1,72 +1,71 @@ -#define REG_R0 0 -#define REG_R1 1 -#define REG_R2 2 -#define REG_R3 3 -#define REG_R4 4 -#define REG_R5 5 -#define REG_R6 6 -#define REG_R7 7 -#define REG_R8 8 -#define REG_R9 9 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_HOST_SP 13 -#define REG_LR 14 -#define REG_PC 15 +#define REG_R0 0 +#define REG_R1 1 +#define REG_R2 2 +#define REG_R3 3 +#define REG_R4 4 +#define REG_R5 5 +#define REG_R6 6 +#define REG_R7 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_HOST_SP 13 +#define REG_LR 14 +#define REG_PC 15 -#define REG_ARG0 REG_R0 -#define REG_ARG1 REG_R1 -#define REG_ARG2 REG_R2 -#define REG_ARG3 REG_R3 +#define REG_ARG0 REG_R0 +#define REG_ARG1 REG_R1 +#define REG_ARG2 REG_R2 +#define REG_ARG3 REG_R3 -#define REG_CPUSTATE REG_R10 +#define REG_CPUSTATE REG_R10 -#define REG_TEMP REG_R3 -#define REG_TEMP2 REG_R2 +#define REG_TEMP REG_R3 +#define REG_TEMP2 REG_R2 -#define REG_D0 0 -#define REG_D1 1 -#define REG_D2 2 -#define REG_D3 3 -#define REG_D4 4 -#define REG_D5 5 -#define REG_D6 6 -#define REG_D7 7 -#define REG_D8 8 -#define REG_D9 9 -#define REG_D10 10 -#define REG_D11 11 -#define REG_D12 12 -#define REG_D13 13 -#define REG_D14 14 -#define REG_D15 15 +#define REG_D0 0 +#define REG_D1 1 +#define REG_D2 2 +#define REG_D3 3 +#define REG_D4 4 +#define REG_D5 5 +#define REG_D6 6 +#define REG_D7 7 +#define REG_D8 8 +#define REG_D9 9 +#define REG_D10 10 +#define REG_D11 11 +#define REG_D12 12 +#define REG_D13 13 +#define REG_D14 14 +#define REG_D15 15 -#define REG_D_TEMP REG_D0 -#define REG_Q_TEMP REG_D0 -#define REG_Q_TEMP_2 REG_D2 +#define REG_D_TEMP REG_D0 +#define REG_Q_TEMP REG_D0 +#define REG_Q_TEMP_2 REG_D2 -#define REG_MASK_R0 (1 << REG_R0) -#define REG_MASK_R1 (1 << REG_R1) -#define REG_MASK_R2 (1 << REG_R2) -#define REG_MASK_R3 (1 << REG_R3) -#define REG_MASK_R4 (1 << REG_R4) -#define REG_MASK_R5 (1 << REG_R5) -#define REG_MASK_R6 (1 << REG_R6) -#define REG_MASK_R7 (1 << REG_R7) -#define REG_MASK_R8 (1 << REG_R8) -#define REG_MASK_R9 (1 << REG_R9) -#define REG_MASK_R10 (1 << REG_R10) -#define REG_MASK_R11 (1 << REG_R11) -#define REG_MASK_R12 (1 << REG_R12) -#define REG_MASK_SP (1 << REG_HOST_SP) -#define REG_MASK_LR (1 << REG_LR) -#define REG_MASK_PC (1 << REG_PC) +#define REG_MASK_R0 (1 << REG_R0) +#define REG_MASK_R1 (1 << REG_R1) +#define REG_MASK_R2 (1 << REG_R2) +#define REG_MASK_R3 (1 << REG_R3) +#define REG_MASK_R4 (1 << REG_R4) +#define REG_MASK_R5 (1 << REG_R5) +#define REG_MASK_R6 (1 << REG_R6) +#define REG_MASK_R7 (1 << REG_R7) +#define REG_MASK_R8 (1 << REG_R8) +#define REG_MASK_R9 (1 << REG_R9) +#define REG_MASK_R10 (1 << REG_R10) +#define REG_MASK_R11 (1 << REG_R11) +#define REG_MASK_R12 (1 << REG_R12) +#define REG_MASK_SP (1 << REG_HOST_SP) +#define REG_MASK_LR (1 << REG_LR) +#define REG_MASK_PC (1 << REG_PC) -#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | \ - REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) +#define REG_MASK_LOCAL (REG_MASK_R4 | REG_MASK_R5 | REG_MASK_R6 | REG_MASK_R7 | REG_MASK_R8 | REG_MASK_R9 | REG_MASK_R10 | REG_MASK_R11) -#define CODEGEN_HOST_REGS 7 +#define CODEGEN_HOST_REGS 7 #define CODEGEN_HOST_FP_REGS 8 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_arm_ops.c b/src/codegen_new/codegen_backend_arm_ops.c index 43d1ea090..e56b2f6e5 100644 --- a/src/codegen_new/codegen_backend_arm_ops.c +++ b/src/codegen_new/codegen_backend_arm_ops.c @@ -1,1274 +1,1395 @@ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm_defs.h" -#include "codegen_backend_arm_ops.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm_defs.h" +# include "codegen_backend_arm_ops.h" -#define Rm(x) (x) -#define Rs(x) ((x) << 8) -#define Rd(x) ((x) << 12) -#define Rt(x) ((x) << 12) -#define Rn(x) ((x) << 16) -#define Rt2(x) ((x) << 16) +# define Rm(x) (x) +# define Rs(x) ((x) << 8) +# define Rd(x) ((x) << 12) +# define Rt(x) ((x) << 12) +# define Rn(x) ((x) << 16) +# define Rt2(x) ((x) << 16) -#define Vm(x) (x) -#define Vd(x) ((x) << 12) -#define Vn(x) ((x) << 16) +# define Vm(x) (x) +# define Vd(x) ((x) << 12) +# define Vn(x) ((x) << 16) -#define DATA_OFFSET_UP (1 << 23) -#define DATA_OFFSET_DOWN (0 << 23) +# define DATA_OFFSET_UP (1 << 23) +# define DATA_OFFSET_DOWN (0 << 23) -#define OPCODE_SHIFT 20 -#define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) -#define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) -#define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) -#define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) -#define OPCODE_B (0xa0 << OPCODE_SHIFT) -#define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) -#define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) -#define OPCODE_BL (0xb0 << OPCODE_SHIFT) -#define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) -#define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) -#define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) -#define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) -#define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) -#define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) -#define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) -#define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) -#define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) -#define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) -#define OPCODE_LDRB_IMM (0x55 << OPCODE_SHIFT) -#define OPCODE_LDRB_REG (0x7d << OPCODE_SHIFT) -#define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) -#define OPCODE_MOVT_IMM (0x34 << OPCODE_SHIFT) -#define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) -#define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) -#define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) -#define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) -#define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) -#define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) -#define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) -#define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) -#define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) -#define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) -#define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) -#define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) -#define OPCODE_STRB_REG (0x7c << OPCODE_SHIFT) -#define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) -#define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) -#define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) -#define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) +# define OPCODE_SHIFT 20 +# define OPCODE_ADD_IMM (0x28 << OPCODE_SHIFT) +# define OPCODE_ADD_REG (0x08 << OPCODE_SHIFT) +# define OPCODE_AND_IMM (0x20 << OPCODE_SHIFT) +# define OPCODE_AND_REG (0x00 << OPCODE_SHIFT) +# define OPCODE_B (0xa0 << OPCODE_SHIFT) +# define OPCODE_BIC_IMM (0x3c << OPCODE_SHIFT) +# define OPCODE_BIC_REG (0x1c << OPCODE_SHIFT) +# define OPCODE_BL (0xb0 << OPCODE_SHIFT) +# define OPCODE_CMN_IMM (0x37 << OPCODE_SHIFT) +# define OPCODE_CMN_REG (0x17 << OPCODE_SHIFT) +# define OPCODE_CMP_IMM (0x35 << OPCODE_SHIFT) +# define OPCODE_CMP_REG (0x15 << OPCODE_SHIFT) +# define OPCODE_EOR_IMM (0x22 << OPCODE_SHIFT) +# define OPCODE_EOR_REG (0x02 << OPCODE_SHIFT) +# define OPCODE_LDMIA_WB (0x8b << OPCODE_SHIFT) +# define OPCODE_LDR_IMM (0x51 << OPCODE_SHIFT) +# define OPCODE_LDR_IMM_POST (0x41 << OPCODE_SHIFT) +# define OPCODE_LDR_REG (0x79 << OPCODE_SHIFT) +# define OPCODE_LDRB_IMM (0x55 << OPCODE_SHIFT) +# define OPCODE_LDRB_REG (0x7d << OPCODE_SHIFT) +# define OPCODE_MOV_IMM (0x3a << OPCODE_SHIFT) +# define OPCODE_MOVT_IMM (0x34 << OPCODE_SHIFT) +# define OPCODE_MOVW_IMM (0x30 << OPCODE_SHIFT) +# define OPCODE_MOV_REG (0x1a << OPCODE_SHIFT) +# define OPCODE_MVN_REG (0x1e << OPCODE_SHIFT) +# define OPCODE_ORR_IMM (0x38 << OPCODE_SHIFT) +# define OPCODE_ORR_REG (0x18 << OPCODE_SHIFT) +# define OPCODE_RSB_IMM (0x26 << OPCODE_SHIFT) +# define OPCODE_RSB_REG (0x06 << OPCODE_SHIFT) +# define OPCODE_STMDB_WB (0x92 << OPCODE_SHIFT) +# define OPCODE_STR_IMM (0x50 << OPCODE_SHIFT) +# define OPCODE_STR_IMM_WB (0x52 << OPCODE_SHIFT) +# define OPCODE_STR_REG (0x78 << OPCODE_SHIFT) +# define OPCODE_STRB_IMM (0x54 << OPCODE_SHIFT) +# define OPCODE_STRB_REG (0x7c << OPCODE_SHIFT) +# define OPCODE_SUB_IMM (0x24 << OPCODE_SHIFT) +# define OPCODE_SUB_REG (0x04 << OPCODE_SHIFT) +# define OPCODE_TST_IMM (0x31 << OPCODE_SHIFT) +# define OPCODE_TST_REG (0x11 << OPCODE_SHIFT) -#define OPCODE_BFI 0xe7c00010 -#define OPCODE_BLX 0xe12fff30 -#define OPCODE_BX 0xe12fff10 -#define OPCODE_LDRH_IMM 0xe1d000b0 -#define OPCODE_LDRH_REG 0xe19000b0 -#define OPCODE_STRH_IMM 0xe1c000b0 -#define OPCODE_STRH_REG 0xe18000b0 -#define OPCODE_SXTB 0xe6af0070 -#define OPCODE_SXTH 0xe6bf0070 -#define OPCODE_UADD8 0xe6500f90 -#define OPCODE_UADD16 0xe6500f10 -#define OPCODE_USUB8 0xe6500ff0 -#define OPCODE_USUB16 0xe6500f70 -#define OPCODE_UXTB 0xe6ef0070 -#define OPCODE_UXTH 0xe6ff0070 -#define OPCODE_VABS_D 0xeeb00bc0 -#define OPCODE_VADD 0xee300b00 -#define OPCODE_VADD_I8 0xf2000800 -#define OPCODE_VADD_I16 0xf2100800 -#define OPCODE_VADD_I32 0xf2200800 -#define OPCODE_VADD_F32 0xf2000d00 -#define OPCODE_VAND_D 0xf2000110 -#define OPCODE_VBIC_D 0xf2100110 -#define OPCODE_VCEQ_F32 0xf2000e00 -#define OPCODE_VCEQ_I8 0xf3000810 -#define OPCODE_VCEQ_I16 0xf3100810 -#define OPCODE_VCEQ_I32 0xf3200810 -#define OPCODE_VCGE_F32 0xf3000e00 -#define OPCODE_VCGT_F32 0xf3200e00 -#define OPCODE_VCGT_S8 0xf2000300 -#define OPCODE_VCGT_S16 0xf2100300 -#define OPCODE_VCGT_S32 0xf2200300 -#define OPCODE_VCMP_D 0xeeb40b40 -#define OPCODE_VCVT_D_IS 0xeeb80bc0 -#define OPCODE_VCVT_D_S 0xeeb70ac0 -#define OPCODE_VCVT_F32_S32 0xf3bb0700 -#define OPCODE_VCVT_IS_D 0xeebd0bc0 -#define OPCODE_VCVT_S32_F32 0xf3bb0600 -#define OPCODE_VCVT_S_D 0xeeb70bc0 -#define OPCODE_VCVTR_IS_D 0xeebd0b40 -#define OPCODE_VDIV 0xee800b00 -#define OPCODE_VDIV_S 0xee800a00 -#define OPCODE_VDUP_32 0xf3b40c00 -#define OPCODE_VEOR_D 0xf3000110 -#define OPCODE_VLDR_D 0xed900b00 -#define OPCODE_VLDR_S 0xed900a00 -#define OPCODE_VMAX_F32 0xf200f00 -#define OPCODE_VMIN_F32 0xf220f00 -#define OPCODE_VMOV_32_S 0xee100a10 -#define OPCODE_VMOV_64_D 0xec500b10 -#define OPCODE_VMOV_D_64 0xec400b10 -#define OPCODE_VMOV_S_32 0xee000a10 -#define OPCODE_VMOV_D_D 0xeeb00b40 -#define OPCODE_VMOVN_I32 0xf3b60200 -#define OPCODE_VMOVN_I64 0xf3ba0200 -#define OPCODE_VMOV_F32_ONE 0xf2870f10 -#define OPCODE_VMRS_APSR 0xeef1fa10 -#define OPCODE_VMSR_FPSCR 0xeee10a10 -#define OPCODE_VMUL 0xee200b00 -#define OPCODE_VMUL_F32 0xf3000d10 -#define OPCODE_VMUL_S16 0xf2100910 -#define OPCODE_VMULL_S16 0xf2900c00 -#define OPCODE_VNEG_D 0xeeb10b40 -#define OPCODE_VORR_D 0xf2200110 -#define OPCODE_VPADDL_S16 0xf3b40200 -#define OPCODE_VPADDL_S32 0xf3b80200 -#define OPCODE_VPADDL_Q_S32 0xf3b80240 -#define OPCODE_VQADD_S8 0xf2000010 -#define OPCODE_VQADD_S16 0xf2100010 -#define OPCODE_VQADD_U8 0xf3000010 -#define OPCODE_VQADD_U16 0xf3100010 -#define OPCODE_VQMOVN_S16 0xf3b20280 -#define OPCODE_VQMOVN_S32 0xf3b60280 -#define OPCODE_VQMOVN_U16 0xf3b202c0 -#define OPCODE_VQSUB_S8 0xf2000210 -#define OPCODE_VQSUB_S16 0xf2100210 -#define OPCODE_VQSUB_U8 0xf3000210 -#define OPCODE_VQSUB_U16 0xf3100210 -#define OPCODE_VSHL_D_IMM_16 0xf2900510 -#define OPCODE_VSHL_D_IMM_32 0xf2a00510 -#define OPCODE_VSHL_D_IMM_64 0xf2800590 -#define OPCODE_VSHR_D_S16 0xf2900010 -#define OPCODE_VSHR_D_S32 0xf2a00010 -#define OPCODE_VSHR_D_S64 0xf2800090 -#define OPCODE_VSHR_D_U16 0xf3900010 -#define OPCODE_VSHR_D_U32 0xf3a00010 -#define OPCODE_VSHR_D_U64 0xf3800090 -#define OPCODE_VSHRN 0xf2800810 -#define OPCODE_VSQRT_D 0xeeb10bc0 -#define OPCODE_VSQRT_S 0xeeb10ac0 -#define OPCODE_VSTR_D 0xed800b00 -#define OPCODE_VSTR_S 0xed800a00 -#define OPCODE_VSUB 0xee300b40 -#define OPCODE_VSUB_I8 0xf3000800 -#define OPCODE_VSUB_I16 0xf3100800 -#define OPCODE_VSUB_I32 0xf3200800 -#define OPCODE_VSUB_F32 0xf3000d00 -#define OPCODE_VZIP_D8 0xf3b20180 -#define OPCODE_VZIP_D16 0xf3b60180 -#define OPCODE_VZIP_D32 0xf3ba0080 +# define OPCODE_BFI 0xe7c00010 +# define OPCODE_BLX 0xe12fff30 +# define OPCODE_BX 0xe12fff10 +# define OPCODE_LDRH_IMM 0xe1d000b0 +# define OPCODE_LDRH_REG 0xe19000b0 +# define OPCODE_STRH_IMM 0xe1c000b0 +# define OPCODE_STRH_REG 0xe18000b0 +# define OPCODE_SXTB 0xe6af0070 +# define OPCODE_SXTH 0xe6bf0070 +# define OPCODE_UADD8 0xe6500f90 +# define OPCODE_UADD16 0xe6500f10 +# define OPCODE_USUB8 0xe6500ff0 +# define OPCODE_USUB16 0xe6500f70 +# define OPCODE_UXTB 0xe6ef0070 +# define OPCODE_UXTH 0xe6ff0070 +# define OPCODE_VABS_D 0xeeb00bc0 +# define OPCODE_VADD 0xee300b00 +# define OPCODE_VADD_I8 0xf2000800 +# define OPCODE_VADD_I16 0xf2100800 +# define OPCODE_VADD_I32 0xf2200800 +# define OPCODE_VADD_F32 0xf2000d00 +# define OPCODE_VAND_D 0xf2000110 +# define OPCODE_VBIC_D 0xf2100110 +# define OPCODE_VCEQ_F32 0xf2000e00 +# define OPCODE_VCEQ_I8 0xf3000810 +# define OPCODE_VCEQ_I16 0xf3100810 +# define OPCODE_VCEQ_I32 0xf3200810 +# define OPCODE_VCGE_F32 0xf3000e00 +# define OPCODE_VCGT_F32 0xf3200e00 +# define OPCODE_VCGT_S8 0xf2000300 +# define OPCODE_VCGT_S16 0xf2100300 +# define OPCODE_VCGT_S32 0xf2200300 +# define OPCODE_VCMP_D 0xeeb40b40 +# define OPCODE_VCVT_D_IS 0xeeb80bc0 +# define OPCODE_VCVT_D_S 0xeeb70ac0 +# define OPCODE_VCVT_F32_S32 0xf3bb0700 +# define OPCODE_VCVT_IS_D 0xeebd0bc0 +# define OPCODE_VCVT_S32_F32 0xf3bb0600 +# define OPCODE_VCVT_S_D 0xeeb70bc0 +# define OPCODE_VCVTR_IS_D 0xeebd0b40 +# define OPCODE_VDIV 0xee800b00 +# define OPCODE_VDIV_S 0xee800a00 +# define OPCODE_VDUP_32 0xf3b40c00 +# define OPCODE_VEOR_D 0xf3000110 +# define OPCODE_VLDR_D 0xed900b00 +# define OPCODE_VLDR_S 0xed900a00 +# define OPCODE_VMAX_F32 0xf200f00 +# define OPCODE_VMIN_F32 0xf220f00 +# define OPCODE_VMOV_32_S 0xee100a10 +# define OPCODE_VMOV_64_D 0xec500b10 +# define OPCODE_VMOV_D_64 0xec400b10 +# define OPCODE_VMOV_S_32 0xee000a10 +# define OPCODE_VMOV_D_D 0xeeb00b40 +# define OPCODE_VMOVN_I32 0xf3b60200 +# define OPCODE_VMOVN_I64 0xf3ba0200 +# define OPCODE_VMOV_F32_ONE 0xf2870f10 +# define OPCODE_VMRS_APSR 0xeef1fa10 +# define OPCODE_VMSR_FPSCR 0xeee10a10 +# define OPCODE_VMUL 0xee200b00 +# define OPCODE_VMUL_F32 0xf3000d10 +# define OPCODE_VMUL_S16 0xf2100910 +# define OPCODE_VMULL_S16 0xf2900c00 +# define OPCODE_VNEG_D 0xeeb10b40 +# define OPCODE_VORR_D 0xf2200110 +# define OPCODE_VPADDL_S16 0xf3b40200 +# define OPCODE_VPADDL_S32 0xf3b80200 +# define OPCODE_VPADDL_Q_S32 0xf3b80240 +# define OPCODE_VQADD_S8 0xf2000010 +# define OPCODE_VQADD_S16 0xf2100010 +# define OPCODE_VQADD_U8 0xf3000010 +# define OPCODE_VQADD_U16 0xf3100010 +# define OPCODE_VQMOVN_S16 0xf3b20280 +# define OPCODE_VQMOVN_S32 0xf3b60280 +# define OPCODE_VQMOVN_U16 0xf3b202c0 +# define OPCODE_VQSUB_S8 0xf2000210 +# define OPCODE_VQSUB_S16 0xf2100210 +# define OPCODE_VQSUB_U8 0xf3000210 +# define OPCODE_VQSUB_U16 0xf3100210 +# define OPCODE_VSHL_D_IMM_16 0xf2900510 +# define OPCODE_VSHL_D_IMM_32 0xf2a00510 +# define OPCODE_VSHL_D_IMM_64 0xf2800590 +# define OPCODE_VSHR_D_S16 0xf2900010 +# define OPCODE_VSHR_D_S32 0xf2a00010 +# define OPCODE_VSHR_D_S64 0xf2800090 +# define OPCODE_VSHR_D_U16 0xf3900010 +# define OPCODE_VSHR_D_U32 0xf3a00010 +# define OPCODE_VSHR_D_U64 0xf3800090 +# define OPCODE_VSHRN 0xf2800810 +# define OPCODE_VSQRT_D 0xeeb10bc0 +# define OPCODE_VSQRT_S 0xeeb10ac0 +# define OPCODE_VSTR_D 0xed800b00 +# define OPCODE_VSTR_S 0xed800a00 +# define OPCODE_VSUB 0xee300b40 +# define OPCODE_VSUB_I8 0xf3000800 +# define OPCODE_VSUB_I16 0xf3100800 +# define OPCODE_VSUB_I32 0xf3200800 +# define OPCODE_VSUB_F32 0xf3000d00 +# define OPCODE_VZIP_D8 0xf3b20180 +# define OPCODE_VZIP_D16 0xf3b60180 +# define OPCODE_VZIP_D32 0xf3ba0080 -#define B_OFFSET(x) (((x) >> 2) & 0xffffff) +# define B_OFFSET(x) (((x) >> 2) & 0xffffff) -#define SHIFT_TYPE_SHIFT 5 -#define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_SHIFT 5 +# define SHIFT_TYPE_LSL (0 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_LSR (1 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_ASR (2 << SHIFT_TYPE_SHIFT) +# define SHIFT_TYPE_ROR (3 << SHIFT_TYPE_SHIFT) -#define SHIFT_TYPE_IMM (0 << 4) -#define SHIFT_TYPE_REG (1 << 4) +# define SHIFT_TYPE_IMM (0 << 4) +# define SHIFT_TYPE_REG (1 << 4) -#define SHIFT_IMM_SHIFT 7 -#define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_ROR_IMM(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_IMM_SHIFT 7 +# define SHIFT_ASR_IMM(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_LSL_IMM(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_LSR_IMM(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) +# define SHIFT_ROR_IMM(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_IMM | ((x) << SHIFT_IMM_SHIFT)) -#define SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x)) -#define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x)) -#define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x)) -#define SHIFT_ROR_REG(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_ASR_REG(x) (SHIFT_TYPE_ASR | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_LSL_REG(x) (SHIFT_TYPE_LSL | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_LSR_REG(x) (SHIFT_TYPE_LSR | SHIFT_TYPE_REG | Rs(x)) +# define SHIFT_ROR_REG(x) (SHIFT_TYPE_ROR | SHIFT_TYPE_REG | Rs(x)) -#define BFI_lsb(lsb) ((lsb) << 7) -#define BFI_msb(msb) ((msb) << 16) +# define BFI_lsb(lsb) ((lsb) << 7) +# define BFI_msb(msb) ((msb) << 16) -#define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) +# define UXTB_ROTATE(rotate) (((rotate) >> 3) << 10) -#define MOVT_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) -#define MOVW_IMM(imm) (((imm) & 0xfff) | (((imm) & 0xf000) << 4)) +# define MOVT_IMM(imm) (((imm) &0xfff) | (((imm) &0xf000) << 4)) +# define MOVW_IMM(imm) (((imm) &0xfff) | (((imm) &0xf000) << 4)) -#define LDRH_IMM(imm) (((imm) & 0xf) | (((imm) & 0xf0) << 4)) -#define STRH_IMM(imm) LDRH_IMM(imm) +# define LDRH_IMM(imm) (((imm) &0xf) | (((imm) &0xf0) << 4)) +# define STRH_IMM(imm) LDRH_IMM(imm) -#define VSHIFT_IMM(shift) ((shift) << 16) +# define VSHIFT_IMM(shift) ((shift) << 16) -#define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) +# define VSHIFT_IMM_32(shift) (((16 - (shift)) | 0x10) << 16) -#define VDUP_32_IMM(imm) ((imm) << 19) +# define VDUP_32_IMM(imm) ((imm) << 19) static void codegen_allocate_new_block(codeblock_t *block); -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static void codegen_allocate_new_block(codeblock_t *block) +static void +codegen_allocate_new_block(codeblock_t *block) { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - uint32_t offset = ((uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos]) - 8; + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + uint32_t offset = ((uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos]) - 8; - /*Add a jump instruction to the new block*/ - *(uint32_t *)&block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); + /*Add a jump instruction to the new block*/ + *(uint32_t *) &block_write_data[block_pos] = COND_AL | OPCODE_B | B_OFFSET(offset); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -static inline void codegen_alloc_4(codeblock_t *block) +static inline void +codegen_alloc_4(codeblock_t *block) { - if (block_pos >= (BLOCK_MAX-4)) - codegen_allocate_new_block(block); + if (block_pos >= (BLOCK_MAX - 4)) + codegen_allocate_new_block(block); } -void codegen_alloc(codeblock_t *block, int size) +void +codegen_alloc(codeblock_t *block, int size) { - if (block_pos >= (BLOCK_MAX-size)) - codegen_allocate_new_block(block); + if (block_pos >= (BLOCK_MAX - size)) + codegen_allocate_new_block(block); } -static inline uint32_t arm_data_offset(int offset) +static inline uint32_t +arm_data_offset(int offset) { - if (offset < -0xffc || offset > 0xffc) - fatal("arm_data_offset out of range - %i\n", offset); + if (offset < -0xffc || offset > 0xffc) + fatal("arm_data_offset out of range - %i\n", offset); - if (offset >= 0) - return offset | DATA_OFFSET_UP; - return (-offset) | DATA_OFFSET_DOWN; + if (offset >= 0) + return offset | DATA_OFFSET_UP; + return (-offset) | DATA_OFFSET_DOWN; } -static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) +static inline int +get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { - int shift = 0; - if (!(imm_data & 0xffff)) - { - shift += 16; - imm_data >>= 16; - } - if (!(imm_data & 0xff)) - { - shift += 8; - imm_data >>= 8; - } - if (!(imm_data & 0xf)) - { - shift += 4; - imm_data >>= 4; - } - if (!(imm_data & 0x3)) - { - shift += 2; - imm_data >>= 2; - } - if (imm_data > 0xff) /*Note - should handle rotation round the word*/ - return 0; - *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); - return 1; + int shift = 0; + if (!(imm_data & 0xffff)) { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ + return 0; + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; } -static inline int in_range(void *addr, void *base) +static inline int +in_range(void *addr, void *base) { - int diff = (uintptr_t)addr - (uintptr_t)base; + int diff = (uintptr_t) addr - (uintptr_t) base; - if (diff < -4095 || diff > 4095) - return 0; - return 1; + if (diff < -4095 || diff > 4095) + return 0; + return 1; } void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -//void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); +// void host_arm_ORR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); -void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_SUB_IMM(block, dst_reg, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_ADD_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_ADD_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_ADD_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_ADD_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_ADD_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_AND_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else if (get_arm_imm(~imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_AND_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_AND_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_AND_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_AND_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_B(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_B(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R3, dest_addr); - host_arm_BX(block, REG_R3); - } - else - codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BX(block, REG_R3); + } else + codegen_addlong(block, COND_AL | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) +void +host_arm_BFI(codeblock_t *block, int dst_reg, int src_reg, int lsb, int width) { - codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); + codegen_addlong(block, OPCODE_BFI | Rd(dst_reg) | Rm(src_reg) | BFI_lsb(lsb) | BFI_msb((lsb + width) - 1)); } -void host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_BIC_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else if (get_arm_imm(~imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_BIC_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else if (get_arm_imm(~imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_AND_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_BIC_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_BIC_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_BIC_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_BIC_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_BL(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BL(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R3, dest_addr); - host_arm_BLX(block, REG_R3); - } - else - codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R3, dest_addr); + host_arm_BLX(block, REG_R3); + } else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } -void host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BL_r1(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - { - host_arm_MOV_IMM(block, REG_R1, dest_addr); - host_arm_BLX(block, REG_R1); - } - else - codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) { + host_arm_MOV_IMM(block, REG_R1, dest_addr); + host_arm_BLX(block, REG_R1); + } else + codegen_addlong(block, COND_AL | OPCODE_BL | B_OFFSET(offset)); } -void host_arm_BLX(codeblock_t *block, int addr_reg) +void +host_arm_BLX(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } -uint32_t *host_arm_BCC_(codeblock_t *block) +uint32_t * +host_arm_BCC_(codeblock_t *block) { - codegen_addlong(block, COND_CC | OPCODE_B); + codegen_addlong(block, COND_CC | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BCS_(codeblock_t *block) +uint32_t * +host_arm_BCS_(codeblock_t *block) { - codegen_addlong(block, COND_CS | OPCODE_B); + codegen_addlong(block, COND_CS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BEQ_(codeblock_t *block) +uint32_t * +host_arm_BEQ_(codeblock_t *block) { - codegen_addlong(block, COND_EQ | OPCODE_B); + codegen_addlong(block, COND_EQ | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BGE_(codeblock_t *block) +uint32_t * +host_arm_BGE_(codeblock_t *block) { - codegen_addlong(block, COND_GE | OPCODE_B); + codegen_addlong(block, COND_GE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BGT_(codeblock_t *block) +uint32_t * +host_arm_BGT_(codeblock_t *block) { - codegen_addlong(block, COND_GT | OPCODE_B); + codegen_addlong(block, COND_GT | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BHI_(codeblock_t *block) +uint32_t * +host_arm_BHI_(codeblock_t *block) { - codegen_addlong(block, COND_HI | OPCODE_B); + codegen_addlong(block, COND_HI | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLE_(codeblock_t *block) +uint32_t * +host_arm_BLE_(codeblock_t *block) { - codegen_addlong(block, COND_LE | OPCODE_B); + codegen_addlong(block, COND_LE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLS_(codeblock_t *block) +uint32_t * +host_arm_BLS_(codeblock_t *block) { - codegen_addlong(block, COND_LS | OPCODE_B); + codegen_addlong(block, COND_LS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BLT_(codeblock_t *block) +uint32_t * +host_arm_BLT_(codeblock_t *block) { - codegen_addlong(block, COND_LT | OPCODE_B); + codegen_addlong(block, COND_LT | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BMI_(codeblock_t *block) +uint32_t * +host_arm_BMI_(codeblock_t *block) { - codegen_addlong(block, COND_MI | OPCODE_B); + codegen_addlong(block, COND_MI | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BNE_(codeblock_t *block) +uint32_t * +host_arm_BNE_(codeblock_t *block) { - codegen_addlong(block, COND_NE | OPCODE_B); + codegen_addlong(block, COND_NE | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BPL_(codeblock_t *block) +uint32_t * +host_arm_BPL_(codeblock_t *block) { - codegen_addlong(block, COND_PL | OPCODE_B); + codegen_addlong(block, COND_PL | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BVC_(codeblock_t *block) +uint32_t * +host_arm_BVC_(codeblock_t *block) { - codegen_addlong(block, COND_VC | OPCODE_B); + codegen_addlong(block, COND_VC | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -uint32_t *host_arm_BVS_(codeblock_t *block) +uint32_t * +host_arm_BVS_(codeblock_t *block) { - codegen_addlong(block, COND_VS | OPCODE_B); + codegen_addlong(block, COND_VS | OPCODE_B); - return (uint32_t *)&block_write_data[block_pos - 4]; + return (uint32_t *) &block_write_data[block_pos - 4]; } -void host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BEQ(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BEQ - out of range %08x %i\n", offset, offset); - codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); + codegen_addlong(block, COND_EQ | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) +void +host_arm_BNE(codeblock_t *block, uintptr_t dest_addr) { - uint32_t offset; + uint32_t offset; - codegen_alloc_4(block); - offset = (dest_addr - (uintptr_t)&block_write_data[block_pos]) - 8; + codegen_alloc_4(block); + offset = (dest_addr - (uintptr_t) &block_write_data[block_pos]) - 8; - if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) - fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); + if ((offset & 0xfe000000) && (offset & 0xfe000000) != 0xfe000000) + fatal("host_arm_BNE - out of range %08x %i\n", offset, offset); - codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); + codegen_addlong(block, COND_NE | OPCODE_B | B_OFFSET(offset)); } -void host_arm_BX(codeblock_t *block, int addr_reg) +void +host_arm_BX(codeblock_t *block, int addr_reg) { - codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); + codegen_addlong(block, OPCODE_BLX | Rm(addr_reg)); } -void host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) +void +host_arm_CMN_IMM(codeblock_t *block, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_CMP_IMM(block, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_CMP_IMM(block, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_CMN_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_CMN_REG_LSL(block, src_reg, REG_TEMP, 0); + } } -void host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) +void +host_arm_CMN_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_CMN_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) +void +host_arm_CMP_IMM(codeblock_t *block, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_CMN_IMM(block, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_CMN_IMM(block, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_CMP_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_CMP_REG_LSL(block, src_reg, REG_TEMP, 0); + } } -void host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) +void +host_arm_CMP_REG_LSL(codeblock_t *block, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_CMP_REG | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_EOR_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_EOR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_EOR_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_EOR_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_EOR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +void +host_arm_LDMIA_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { - codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); + codegen_addlong(block, COND_AL | OPCODE_LDMIA_WB | Rn(addr_reg) | reg_mask); } -void host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDR_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDR_IMM_POST(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDR_IMM_POST | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_LDR_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_LDR_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_arm_LDRB_ABS(codeblock_t *block, int dst_reg, void *p) { - if (in_range(p, &cpu_state)) - host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("LDRB_ABS - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_LDRB_IMM(block, dst_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("LDRB_ABS - not in range\n"); } -void host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDRB_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDRB_IMM | Rn(addr_reg) | Rd(dst_reg) | arm_data_offset(offset)); } -void host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_LDRB_REG_LSL(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_LDRB_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_LDRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); + codegen_addlong(block, COND_AL | OPCODE_LDRH_IMM | Rn(addr_reg) | Rd(dst_reg) | LDRH_IMM(offset)); } -void host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) +void +host_arm_LDRH_REG(codeblock_t *block, int dst_reg, int addr_reg, int offset_reg) { - codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); + codegen_addlong(block, COND_AL | OPCODE_LDRH_REG | Rn(addr_reg) | Rd(dst_reg) | Rm(offset_reg)); } -void host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) +void +host_arm_MOV_IMM(codeblock_t *block, int dst_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); - } - else - { - host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); - if (imm >> 16) - host_arm_MOVT_IMM(block, dst_reg, imm >> 16); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_MOV_IMM | Rd(dst_reg) | arm_imm); + } else { + host_arm_MOVW_IMM(block, dst_reg, imm & 0xffff); + if (imm >> 16) + host_arm_MOVT_IMM(block, dst_reg, imm >> 16); + } } -void host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_ASR(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_IMM(shift)); } -void host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_ASR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ASR_REG(shift_reg)); } -void host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_LSL_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_REG(shift_reg)); } -void host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_LSR(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_IMM(shift)); } -void host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_LSR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSR_REG(shift_reg)); } -void host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MOV_REG_ROR(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_IMM(shift)); } -void host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) +void +host_arm_MOV_REG_ROR_REG(codeblock_t *block, int dst_reg, int src_reg, int shift_reg) { - codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); + codegen_addlong(block, COND_AL | OPCODE_MOV_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_ROR_REG(shift_reg)); } -void host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +void +host_arm_MOVT_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { - codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); + codegen_addlong(block, COND_AL | OPCODE_MOVT_IMM | Rd(dst_reg) | MOVT_IMM(imm)); } -void host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) +void +host_arm_MOVW_IMM(codeblock_t *block, int dst_reg, uint16_t imm) { - codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); + codegen_addlong(block, COND_AL | OPCODE_MOVW_IMM | Rd(dst_reg) | MOVW_IMM(imm)); } -void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_MVN_REG | Rd(dst_reg) | Rm(src_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, cond | OPCODE_ORR_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_ORR_REG_LSL_cond(block, cond, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, cond | OPCODE_ORR_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_RSB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_RSB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_RSB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_RSB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) +void +host_arm_STMDB_WB(codeblock_t *block, int addr_reg, uint32_t reg_mask) { - codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); + codegen_addlong(block, COND_AL | OPCODE_STMDB_WB | Rn(addr_reg) | reg_mask); } -void host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +void +host_arm_STR_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_STR_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) +void +host_arm_STR_IMM_WB(codeblock_t *block, int src_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_STR_IMM_WB | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_STR_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_STR_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) +void +host_arm_STRB_IMM(codeblock_t *block, int src_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); + codegen_addlong(block, COND_AL | OPCODE_STRB_IMM | Rn(addr_reg) | Rd(src_reg) | arm_data_offset(offset)); } -void host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) +void +host_arm_STRB_REG_LSL(codeblock_t *block, int src_reg, int addr_reg, int offset_reg, int shift) { - codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_STRB_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg) | SHIFT_LSL_IMM(shift)); } -void host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) +void +host_arm_STRH_IMM(codeblock_t *block, int dst_reg, int addr_reg, int offset) { - codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); + codegen_addlong(block, COND_AL | OPCODE_STRH_IMM | Rn(addr_reg) | Rd(dst_reg) | STRH_IMM(offset)); } -void host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) +void +host_arm_STRH_REG(codeblock_t *block, int src_reg, int addr_reg, int offset_reg) { - codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); + codegen_addlong(block, COND_AL | OPCODE_STRH_REG | Rn(addr_reg) | Rd(src_reg) | Rm(offset_reg)); } -void host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) +void +host_arm_SUB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if ((int32_t)imm < 0 && imm != 0x80000000) - { - host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t)imm); - } - else if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); - } + if ((int32_t) imm < 0 && imm != 0x80000000) { + host_arm_ADD_IMM(block, dst_reg, src_reg, -(int32_t) imm); + } else if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_SUB_IMM | Rd(dst_reg) | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_SUB_REG_LSL(block, dst_reg, src_reg, REG_TEMP, 0); + } } -void host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_SUB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSL_IMM(shift)); } -void host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) +void +host_arm_SUB_REG_LSR(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift) { - codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); + codegen_addlong(block, COND_AL | OPCODE_SUB_REG | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m) | SHIFT_LSR_IMM(shift)); } -void host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_SXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_SXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_SXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_SXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) +void +host_arm_TST_IMM(codeblock_t *block, int src_reg, uint32_t imm) { - uint32_t arm_imm; + uint32_t arm_imm; - if (get_arm_imm(imm, &arm_imm)) - { - codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); - } - else - { - host_arm_MOV_IMM(block, REG_TEMP, imm); - host_arm_TST_REG(block, src_reg, REG_TEMP); - } + if (get_arm_imm(imm, &arm_imm)) { + codegen_addlong(block, COND_AL | OPCODE_TST_IMM | Rn(src_reg) | arm_imm); + } else { + host_arm_MOV_IMM(block, REG_TEMP, imm); + host_arm_TST_REG(block, src_reg, REG_TEMP); + } } -void host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) +void +host_arm_TST_REG(codeblock_t *block, int src_reg1, int src_reg2) { - codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); + codegen_addlong(block, COND_AL | OPCODE_TST_REG | Rn(src_reg1) | Rm(src_reg2)); } -void host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_UADD8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_UADD8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_UADD16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_UADD16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_USUB8(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_USUB8 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +void +host_arm_USUB16(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) { - codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); + codegen_addlong(block, COND_AL | OPCODE_USUB16 | Rd(dst_reg) | Rn(src_reg_a) | Rm(src_reg_b)); } -void host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_UXTB(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_UXTB | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) +void +host_arm_UXTH(codeblock_t *block, int dst_reg, int src_reg, int rotate) { - codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); + codegen_addlong(block, OPCODE_UXTH | Rd(dst_reg) | Rm(src_reg) | UXTB_ROTATE(rotate)); } -void host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VABS_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VABS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VADD | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VADD_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VADD_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VADD_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VADD_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VADD_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VAND_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VAND_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VBIC_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VBIC_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) +void +host_arm_VCMP_D(codeblock_t *block, int src_reg_d, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VCMP_D | Rd(src_reg_d) | Rm(src_reg_m)); } -void host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCEQ_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCEQ_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGE_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGE_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VCGT_S32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VCGT_S32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_D_IS(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_IS | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_D_S(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_D_S | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_F32_S32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_F32_S32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_IS_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_IS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_S32_F32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_S32_F32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVT_S_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVT_S_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VCVTR_IS_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VCVTR_IS_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VDIV_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VDIV | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VDIV_S(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VDIV_S | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) +void +host_arm_VDUP_32(codeblock_t *block, int dst_reg, int src_reg_m, int imm) { - codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); + codegen_addlong(block, COND_AL | OPCODE_VDUP_32 | Rd(dst_reg) | Rm(src_reg_m) | VDUP_32_IMM(imm)); } -void host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VEOR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VEOR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm_VLDR_D(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VLDR_D bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_D | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) +void +host_arm_VLDR_S(codeblock_t *block, int dest_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VLDR_S bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VLDR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VLDR_S | Rd(dest_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOV_32_S(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_32_S | Rt(dest_reg) | Vn(src_reg)); } -void host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) +void +host_arm_VMOV_64_D(codeblock_t *block, int dest_reg_low, int dest_reg_high, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_64_D | Rt(dest_reg_low) | Rt2(dest_reg_high) | Vm(src_reg)); } -void host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) +void +host_arm_VMOV_D_64(codeblock_t *block, int dest_reg, int src_reg_low, int src_reg_high) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_64 | Vm(dest_reg) | Rt(src_reg_low) | Rt2(src_reg_high)); } -void host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOV_S_32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_S_32 | Vn(dest_reg) | Rt(src_reg)); } -void host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOV_D_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_D_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOVN_I32(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VMOVN_I32 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VMOVN_I64(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VMOVN_I64 | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) +void +host_arm_VMOV_F32_ONE(codeblock_t *block, int dst_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMOV_F32_ONE | Rd(dst_reg)); } -void host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) +void +host_arm_VMSR_FPSCR(codeblock_t *block, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VMSR_FPSCR | Rd(src_reg)); } -void host_arm_VMRS_APSR(codeblock_t *block) +void +host_arm_VMRS_APSR(codeblock_t *block) { - codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); + codegen_addlong(block, COND_AL | OPCODE_VMRS_APSR); } -void host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMAX_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMAX_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMIN_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMIN_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMUL_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VMUL | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMUL_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VMUL_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMUL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMUL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VMULL_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VMULL_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VNEG_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VNEG_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VORR_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VORR_D | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VPADDL_S16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VPADDL_S16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VPADDL_S32(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VPADDL_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VPADDL_Q_S32(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VPADDL_Q_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQADD_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQADD_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_S8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_S8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_S16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_S16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_U8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_U8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VQSUB_U16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VQSUB_U16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VQMOVN_S16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VQMOVN_S16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VQMOVN_S32(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VQMOVN_S32 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) +void +host_arm_VQMOVN_U16(codeblock_t *block, int dst_reg, int src_reg) { - codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); + codegen_addlong(block, OPCODE_VQMOVN_U16 | Vd(dst_reg) | Vm(src_reg)); } -void host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHL_D_IMM_16(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 15) - fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + if (shift > 15) + fatal("host_arm_VSHL_D_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHL_D_IMM_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 31) - fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + if (shift > 31) + fatal("host_arm_VSHL_D_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHL_D_IMM_64(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 63) - fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); + if (shift > 63) + fatal("host_arm_VSHL_D_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHL_D_IMM_64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(shift)); } -void host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_S16(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 15) - fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); + if (shift > 15) + fatal("host_arm_VSHR_SD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_D_S16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16 - shift)); } -void host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_S32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 31) - fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); + if (shift > 31) + fatal("host_arm_VSHR_SD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_D_S32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32 - shift)); } -void host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_S64(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 63) - fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); + if (shift > 63) + fatal("host_arm_VSHR_SD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_D_S64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64 - shift)); } -void host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_U16(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 15) - fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); - codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16-shift)); + if (shift > 15) + fatal("host_arm_VSHR_UD_IMM_16 : shift > 15\n"); + codegen_addlong(block, OPCODE_VSHR_D_U16 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(16 - shift)); } -void host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_U32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 31) - fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); - codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32-shift)); + if (shift > 31) + fatal("host_arm_VSHR_UD_IMM_32 : shift > 31\n"); + codegen_addlong(block, OPCODE_VSHR_D_U32 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(32 - shift)); } -void host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHR_D_U64(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 63) - fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); - codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64-shift)); + if (shift > 63) + fatal("host_arm_VSHR_UD_IMM_64 : shift > 63\n"); + codegen_addlong(block, OPCODE_VSHR_D_U64 | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM(64 - shift)); } -void host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) +void +host_arm_VSHRN_32(codeblock_t *block, int dst_reg, int src_reg, int shift) { - if (shift > 16) - fatal("host_arm_VSHRN_32 : shift > 16\n"); - codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16-shift)); + if (shift > 16) + fatal("host_arm_VSHRN_32 : shift > 16\n"); + codegen_addlong(block, OPCODE_VSHRN | Vd(dst_reg) | Vm(src_reg) | VSHIFT_IMM_32(16 - shift)); } -void host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VSQRT_D(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VSQRT_D | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) +void +host_arm_VSQRT_S(codeblock_t *block, int dest_reg, int src_reg) { - codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); + codegen_addlong(block, COND_AL | OPCODE_VSQRT_S | Vd(dest_reg) | Vm(src_reg)); } -void host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) +void +host_arm_VSTR_D(codeblock_t *block, int src_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VSTR_D bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_D bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_D | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) +void +host_arm_VSTR_S(codeblock_t *block, int src_reg, int base_reg, int offset) { - if ((offset > 1020) || (offset & 3)) - fatal("VSTR_S bad offset %i\n", offset); - codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); + if ((offset > 1020) || (offset & 3)) + fatal("VSTR_S bad offset %i\n", offset); + codegen_addlong(block, COND_AL | OPCODE_VSTR_S | Rd(src_reg) | Rn(base_reg) | (offset >> 2)); } -void host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_D(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VSUB | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_F32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, COND_AL | OPCODE_VSUB_F32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_I8(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VSUB_I8 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_I16(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VSUB_I16 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) +void +host_arm_VSUB_I32(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m) { - codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); + codegen_addlong(block, OPCODE_VSUB_I32 | Rd(dst_reg) | Rn(src_reg_n) | Rm(src_reg_m)); } -void host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) +void +host_arm_VZIP_D8(codeblock_t *block, int d_reg, int m_reg) { - codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); + codegen_addlong(block, OPCODE_VZIP_D8 | Vd(d_reg) | Vm(m_reg)); } -void host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) +void +host_arm_VZIP_D16(codeblock_t *block, int d_reg, int m_reg) { - codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); + codegen_addlong(block, OPCODE_VZIP_D16 | Vd(d_reg) | Vm(m_reg)); } -void host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) +void +host_arm_VZIP_D32(codeblock_t *block, int d_reg, int m_reg) { - codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); + codegen_addlong(block, OPCODE_VZIP_D32 | Vd(d_reg) | Vm(m_reg)); } #endif diff --git a/src/codegen_new/codegen_backend_arm_ops.h b/src/codegen_new/codegen_backend_arm_ops.h index 7627f51a7..271fbffbd 100644 --- a/src/codegen_new/codegen_backend_arm_ops.h +++ b/src/codegen_new/codegen_backend_arm_ops.h @@ -1,19 +1,19 @@ #define COND_SHIFT 28 -#define COND_EQ (0x0 << COND_SHIFT) -#define COND_NE (0x1 << COND_SHIFT) -#define COND_CS (0x2 << COND_SHIFT) -#define COND_CC (0x3 << COND_SHIFT) -#define COND_MI (0x4 << COND_SHIFT) -#define COND_PL (0x5 << COND_SHIFT) -#define COND_VS (0x6 << COND_SHIFT) -#define COND_VC (0x7 << COND_SHIFT) -#define COND_HI (0x8 << COND_SHIFT) -#define COND_LS (0x9 << COND_SHIFT) -#define COND_GE (0xa << COND_SHIFT) -#define COND_LT (0xb << COND_SHIFT) -#define COND_GT (0xc << COND_SHIFT) -#define COND_LE (0xd << COND_SHIFT) -#define COND_AL (0xe << COND_SHIFT) +#define COND_EQ (0x0 << COND_SHIFT) +#define COND_NE (0x1 << COND_SHIFT) +#define COND_CS (0x2 << COND_SHIFT) +#define COND_CC (0x3 << COND_SHIFT) +#define COND_MI (0x4 << COND_SHIFT) +#define COND_PL (0x5 << COND_SHIFT) +#define COND_VS (0x6 << COND_SHIFT) +#define COND_VC (0x7 << COND_SHIFT) +#define COND_HI (0x8 << COND_SHIFT) +#define COND_LS (0x9 << COND_SHIFT) +#define COND_GE (0xa << COND_SHIFT) +#define COND_LT (0xb << COND_SHIFT) +#define COND_GT (0xc << COND_SHIFT) +#define COND_LE (0xd << COND_SHIFT) +#define COND_AL (0xe << COND_SHIFT) void host_arm_ADD_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); #define host_arm_ADD_REG(block, dst_reg, src_reg_n, src_reg_m) host_arm_ADD_REG_LSL(block, dst_reg, src_reg_n, src_reg_m, 0) @@ -101,12 +101,12 @@ void host_arm_MVN_REG_LSL(codeblock_t *block, int dst_reg, int src_reg, int shif void host_arm_ORR_IMM_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg, uint32_t imm); void host_arm_ORR_REG_LSL_cond(codeblock_t *block, uint32_t cond, int dst_reg, int src_reg_n, int src_reg_m, int shift); -#define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm) +#define host_arm_ORR_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_AL, dst_reg, src_reg, imm) #define host_arm_ORR_REG_LSL(block, dst_reg, src_reg_a, src_reg_b, shift) host_arm_ORR_REG_LSL_cond(block, COND_AL, dst_reg, src_reg_a, src_reg_b, shift) -#define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm) -#define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) -#define host_arm_ORRVS_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_VS, dst_reg, src_reg, imm) +#define host_arm_ORRCC_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_CC, dst_reg, src_reg, imm) +#define host_arm_ORREQ_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_EQ, dst_reg, src_reg, imm) +#define host_arm_ORRVS_IMM(block, dst_reg, src_reg, imm) host_arm_ORR_IMM_cond(block, COND_VS, dst_reg, src_reg, imm) void host_arm_RSB_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t imm); void host_arm_RSB_REG_LSL(codeblock_t *block, int dst_reg, int src_reg_n, int src_reg_m, int shift); diff --git a/src/codegen_new/codegen_backend_arm_uops.c b/src/codegen_new/codegen_backend_arm_uops.c index 8b0990016..4cc0ff38d 100644 --- a/src/codegen_new/codegen_backend_arm_uops.c +++ b/src/codegen_new/codegen_backend_arm_uops.c @@ -1,3502 +1,3375 @@ #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_arm_defs.h" -#include "codegen_backend_arm_ops.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x87.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_arm_defs.h" +# include "codegen_backend_arm_ops.h" +# include "codegen_ir_defs.h" -static inline int get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) +static inline int +get_arm_imm(uint32_t imm_data, uint32_t *arm_imm) { - int shift = 0; - if (!(imm_data & 0xffff)) - { - shift += 16; - imm_data >>= 16; - } - if (!(imm_data & 0xff)) - { - shift += 8; - imm_data >>= 8; - } - if (!(imm_data & 0xf)) - { - shift += 4; - imm_data >>= 4; - } - if (!(imm_data & 0x3)) - { - shift += 2; - imm_data >>= 2; - } - if (imm_data > 0xff) /*Note - should handle rotation round the word*/ - return 0; - *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); - return 1; -} - -static inline int in_range(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; - - if (diff < -4095 || diff > 4095) - return 0; - return 1; -} - -static inline int in_range_h(void *addr, void *base) -{ - int diff = (uintptr_t)addr - (uintptr_t)base; - - if (diff < 0 || diff > 255) - return 0; - return 1; -} - -void host_arm_call(codeblock_t *block, void *dst_addr) -{ - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)dst_addr); - host_arm_BLX(block, REG_R3); -} - -void host_arm_nop(codeblock_t *block) -{ - host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); -} - -#define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf) - -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) - -static int codegen_ADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); - host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); - } - else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - + int shift = 0; + if (!(imm_data & 0xffff)) { + shift += 16; + imm_data >>= 16; + } + if (!(imm_data & 0xff)) { + shift += 8; + imm_data >>= 8; + } + if (!(imm_data & 0xf)) { + shift += 4; + imm_data >>= 4; + } + if (!(imm_data & 0x3)) { + shift += 2; + imm_data >>= 2; + } + if (imm_data > 0xff) /*Note - should handle rotation round the word*/ return 0; + *arm_imm = imm_data | ((((32 - shift) >> 1) & 15) << 8); + return 1; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) + +static inline int +in_range(void *addr, void *base) { -// host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); -// return 0; - - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) - { - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); - host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); - } - else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + int diff = (uintptr_t) addr - (uintptr_t) base; + if (diff < -4095 || diff > 4095) return 0; - + return 1; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) + +static inline int +in_range_h(void *addr, void *base) { - host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + int diff = (uintptr_t) addr - (uintptr_t) base; + + if (diff < 0 || diff > 255) return 0; + return 1; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +void +host_arm_call(codeblock_t *block, void *dst_addr) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); - host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); - host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); - host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ANDN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); - } - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; + host_arm_MOV_IMM(block, REG_R3, (uintptr_t) dst_addr); + host_arm_BLX(block, REG_R3); } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +void +host_arm_nop(codeblock_t *block) { - host_arm_call(block, uop->p); - - return 0; + host_arm_MOV_REG_LSL(block, REG_R0, REG_R0, 0); } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); +# define HOST_REG_GET(reg) (IREG_GET_REG(reg) & 0xf) - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); - host_arm_call(block, uop->p); +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) + +static int +codegen_ADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_ADD_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_ADD_REG(block, REG_TEMP, src_reg_a, src_reg_b); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_ADD_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, 8); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_AND_IMM(block, REG_TEMP, src_reg_b, 0x0000ff00); + host_arm_UADD8(block, dest_reg, src_reg_a, REG_TEMP); + } else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +{ + // host_arm_ADD_IMM(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->imm_data); + // return 0; + + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_ADD_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_ADD_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && src_reg == dest_reg) { + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data << 8); + host_arm_UADD8(block, dest_reg, src_reg, REG_TEMP); + } else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +{ + host_arm_ADD_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); + return 0; +} + +static int +codegen_AND(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VAND_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_AND_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 24); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 16); + host_arm_BIC_REG_LSR(block, dest_reg, src_reg_a, REG_TEMP, 24); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_MVN_REG_LSL(block, REG_TEMP, src_reg_b, 0); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 0x0000ff00); + host_arm_BIC_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_AND_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_AND_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffff0000); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, uop->imm_data | 0xffffff00); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_AND_IMM(block, dest_reg, src_reg, (uop->imm_data << 8) | 0xffff00ff); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_AND_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VBIC_D(block, dest_reg, src_reg_b, src_reg_a); + } else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + + return 0; +} + +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); + host_arm_call(block, uop->p); + host_arm_MOV_REG(block, dest_reg, REG_R0); + + return 0; +} + +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +{ + host_arm_call(block, uop->p); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} + +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); + host_arm_BEQ(block, (uintptr_t) uop->p); + + return 0; +} + +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_arm_CMP_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); + } else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BCC_(block); + *jump_p |= ((((uintptr_t) uop->p - (uintptr_t) jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + + jump_p = host_arm_BHI_(block); + *jump_p |= ((((uintptr_t) uop->p - (uintptr_t) jump_p) - 8) & 0x3fffffc) >> 2; + + return 0; +} + +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCS_(block); + + return 0; +} +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BHI_(block); + + return 0; +} +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGE_(block); + + return 0; +} +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BGT_(block); + + return 0; +} +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVC_(block); + + return 0; +} +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BNE_(block); + + return 0; +} +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BCC_(block); + + return 0; +} +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLS_(block); + + return 0; +} +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLT_(block); + + return 0; +} +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BLE_(block); + + return 0; +} +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BVS_(block); + + return 0; +} +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_CMP_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); + host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); + } else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); + + uop->p = host_arm_BEQ_(block); + + return 0; +} + +static int +codegen_FABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VABS_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VNEG_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VSQRT_D(block, dest_reg, src_reg_a); + } else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); + host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + } else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VCMP_D(block, src_reg_a, src_reg_b); + host_arm_MOV_IMM(block, dest_reg, 0); + host_arm_VMRS_APSR(block); + host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); + host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); + host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0 | C2 | C3); + } else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_FP_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t) codegen_exit_rout); + + *branch_ptr |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_ptr) - 8) & 0x3fffffc) >> 2; + + return 0; +} +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_ptr; + + if (!in_range(&cr0, &cpu_state)) + fatal("codegen_MMX_ENTER - out of range\n"); + + host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cr0 - (uintptr_t) &cpu_state); + host_arm_TST_IMM(block, REG_TEMP, 0xc); + branch_ptr = host_arm_BEQ_(block); + + host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.oldpc - (uintptr_t) &cpu_state); + host_arm_MOV_IMM(block, REG_ARG0, 7); + host_arm_call(block, x86_int); + host_arm_B(block, (uintptr_t) codegen_exit_rout); + + *branch_ptr |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_ptr) - 8) & 0x3fffffc) >> 2; + + host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[0] - (uintptr_t) &cpu_state); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.tag[4] - (uintptr_t) &cpu_state); + host_arm_MOV_IMM(block, REG_TEMP, 0); + host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.TOP - (uintptr_t) &cpu_state); + host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t) &cpu_state.ismmx - (uintptr_t) &cpu_state); + + return 0; +} + +static int +codegen_JMP(codeblock_t *block, uop_t *uop) +{ + host_arm_B(block, (uintptr_t) uop->p); + + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + } else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + + return 0; +} +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); + return 0; +} +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); + return 0; +} +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); + return 0; +} + +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); + host_arm_UXTH(block, REG_ARG0, src_reg, 0); + host_arm_MOV_IMM(block, REG_ARG1, (uint32_t) uop->p); + host_arm_call(block, loadseg); + host_arm_TST_REG(block, REG_R0, REG_R0); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_long); + } else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } else if (REG_IS_L(dest_size)) { host_arm_MOV_REG(block, dest_reg, REG_R0); + } - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) { - host_arm_call(block, uop->p); - host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - return 0; + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_arm_BL(block, (uintptr_t) codegen_mem_load_quad); + } else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 8); + } else if (REG_IS_BH(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 8, 8); + } else if (REG_IS_W(dest_size)) { + host_arm_BFI(block, dest_reg, REG_R0, 0, 16); + } else if (REG_IS_L(dest_size)) { + host_arm_MOV_REG(block, dest_reg, REG_R0); + } else if (REG_IS_Q(dest_size)) { + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } + + return 0; +} +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_load_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); + + return 0; +} +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_load_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); - host_arm_BEQ(block, (uintptr_t)uop->p); + host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_long); + } else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + if (REG_IS_B(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + } else if (REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_arm_MOV_REG(block, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_quad); + } else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - uop->p = host_arm_BNE_(block); - - return 0; -} -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_arm_CMP_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_CMP_IMM(block, REG_TEMP, uop->imm_data); - } - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_store_byte); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - jump_p = host_arm_BCC_(block); - *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; - - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_store_word); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); - jump_p = host_arm_BHI_(block); - *jump_p |= ((((uintptr_t)uop->p - (uintptr_t)jump_p) - 8) & 0x3fffffc) >> 2; + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - return 0; + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + host_arm_MOV_IMM(block, REG_R1, uop->imm_data); + host_arm_BL(block, (uintptr_t) codegen_mem_store_long); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_single); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); + + host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); + if (uop->imm_data) + host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_mem_store_double); + host_arm_TST_REG(block, REG_R1, REG_R1); + host_arm_BNE(block, (uintptr_t) codegen_exit_rout); + + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_MOV(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) { + host_arm_BFI(block, dest_reg, src_reg, 8, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_arm_VMOV_D_D(block, dest_reg, src_reg); + } else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - uop->p = host_arm_BCS_(block); - - return 0; -} -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BHI_(block); - - return 0; -} -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BGE_(block); - - return 0; -} -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BGT_(block); - - return 0; -} -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BVC_(block); - - return 0; -} -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BNE_(block); - - return 0; -} -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BCC_(block); - - return 0; -} -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLS_(block); - - return 0; -} -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLT_(block); - - return 0; -} -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BLE_(block); - - return 0; -} -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BVS_(block); - - return 0; -} -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_CMP_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 16); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 16); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg_a, 24); - host_arm_CMP_REG_LSL(block, REG_TEMP, src_reg_b, 24); - } - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); - - uop->p = host_arm_BEQ_(block); - - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VABS_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size)) { + host_arm_MOV_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size)) { + host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); + host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); + } else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - return 0; + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t) uop->p); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VNEG_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VSQRT_D(block, dest_reg, src_reg_a); - } - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_FTST(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_arm_VSUB_D(block, REG_D_TEMP, REG_D_TEMP, REG_D_TEMP); - host_arm_VCMP_D(block, src_reg_a, REG_D_TEMP); - host_arm_MOV_IMM(block, dest_reg, 0); - host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); - } - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VADD_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm_SXTB(block, dest_reg, src_reg, 0); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm_SXTB(block, dest_reg, src_reg, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm_SXTH(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_arm_SXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm_SXTB(block, REG_TEMP, src_reg, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_FCOM(codeblock_t *block, uop_t *uop) +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VCMP_D(block, src_reg_a, src_reg_b); - host_arm_MOV_IMM(block, dest_reg, 0); - host_arm_VMRS_APSR(block); - host_arm_ORREQ_IMM(block, dest_reg, dest_reg, C3); - host_arm_ORRCC_IMM(block, dest_reg, dest_reg, C0); - host_arm_ORRVS_IMM(block, dest_reg, dest_reg, C0|C2|C3); - } - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FDIV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VDIV_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VMUL_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_arm_VSUB_D(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - - if (!in_range(&cr0, &cpu_state)) - fatal("codegen_FP_ENTER - out of range\n"); - - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm_BEQ_(block); - - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_ARG0, 7); - host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)codegen_exit_rout); - - *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - - return 0; -} -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_ptr; - - if (!in_range(&cr0, &cpu_state)) - fatal("codegen_MMX_ENTER - out of range\n"); - - host_arm_LDR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cr0 - (uintptr_t)&cpu_state); - host_arm_TST_IMM(block, REG_TEMP, 0xc); - branch_ptr = host_arm_BEQ_(block); - - host_arm_MOV_IMM(block, REG_TEMP, uop->imm_data); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.oldpc - (uintptr_t)&cpu_state); - host_arm_MOV_IMM(block, REG_ARG0, 7); - host_arm_call(block, x86_int); - host_arm_B(block, (uintptr_t)codegen_exit_rout); - - *branch_ptr |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_ptr) - 8) & 0x3fffffc) >> 2; - - host_arm_MOV_IMM(block, REG_TEMP, 0x01010101); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[0] - (uintptr_t)&cpu_state); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.tag[4] - (uintptr_t)&cpu_state); + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { host_arm_MOV_IMM(block, REG_TEMP, 0); - host_arm_STR_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.TOP - (uintptr_t)&cpu_state); - host_arm_STRB_IMM(block, REG_TEMP, REG_CPUSTATE, (uintptr_t)&cpu_state.ismmx - (uintptr_t)&cpu_state); - - return 0; -} - -static int codegen_JMP(codeblock_t *block, uop_t *uop) -{ - host_arm_B(block, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_ARG0, src_reg, 0); + host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_arm_VMOV_32_S(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, dest_reg, src_reg, 0); + } else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, dest_reg, src_reg, 8); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, dest_reg, src_reg, 0); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + if (src_reg == dest_reg) + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } + } else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); + host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static double +int64_to_double(int64_t a) +{ + return (double) a; +} +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_arm_SXTH(block, REG_TEMP, src_reg, 0); + host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); + host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + /*ARMv7 has no instructions to convert a 64-bit integer to a double. + For simplicity, call a C function and let the compiler do it.*/ + host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); + host_arm_BL(block, (uintptr_t) int64_to_double); /*Input - R0/R1, Output - D0*/ + host_arm_VMOV_D_D(block, dest_reg, REG_D0); + } else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_fp_round); + host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); + host_arm_BL(block, (uintptr_t) codegen_fp_round); + host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int64_t +x87_fround64(double b) +{ + int64_t a, c; + + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } + + return 0; +} +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_arm_VMOV_D_D(block, dest_reg, src_64_reg); + host_arm_TST_IMM(block, tag_reg, TAG_UINT64); + branch_offset = host_arm_BNE_(block); + + /*VFP/NEON has no instructions to convert a float to 64-bit integer, + so call out to C.*/ + host_arm_VMOV_D_D(block, REG_D0, src_reg); + host_arm_call(block, x87_fround64); + host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); + + *branch_offset |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 8) & 0x3fffffc) >> 2; + } else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size)) { + host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t) uop->p); + if (REG_IS_L(dest_size)) { + host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); + } else if (REG_IS_W(dest_size)) { + host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); + host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); + host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); + host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); + } else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRECPE/VRECPS)*/ + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ + host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); + host_arm_VMOV_F32_ONE(block, REG_D_TEMP); + host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); + host_arm_VDUP_32(block, dest_reg, dest_reg, 0); + } else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); + } else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); + + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); + host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); + host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); + } else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); + host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) { - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); - return 0; -} + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG0, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG1, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG2, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, REG_ARG3, uop->imm_data); - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); - host_arm_UXTH(block, REG_ARG0, src_reg, 0); - host_arm_MOV_IMM(block, REG_ARG1, (uint32_t)uop->p); - host_arm_call(block, loadseg); - host_arm_TST_REG(block, REG_R0, REG_R0); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_long); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm_MOV_REG(block, dest_reg, REG_R0); - } + host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - if (REG_IS_B(dest_size) || REG_IS_BH(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_arm_BL(block, (uintptr_t)codegen_mem_load_quad); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 8); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 8, 8); - } - else if (REG_IS_W(dest_size)) - { - host_arm_BFI(block, dest_reg, REG_R0, 0, 16); - } - else if (REG_IS_L(dest_size)) - { - host_arm_MOV_REG(block, dest_reg, REG_R0); - } - else if (REG_IS_Q(dest_size)) - { - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } + host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_load_single); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - host_arm_VCVT_D_S(block, dest_reg, REG_D_TEMP); - - return 0; -} -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_load_double); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - - return 0; -} - -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - - host_arm_ADD_IMM(block, REG_R0, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_R1, src_reg, 8); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_arm_MOV_REG(block, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_quad); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_c_real); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); + host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_byte); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_word); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - host_arm_MOV_IMM(block, REG_R1, uop->imm_data); - host_arm_BL(block, (uintptr_t)codegen_mem_store_long); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_VCVT_S_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_single); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_REG - %02x\n", uop->dest_reg_a_real); - - host_arm_ADD_REG(block, REG_R0, seg_reg, addr_reg); - if (uop->imm_data) - host_arm_ADD_IMM(block, REG_R0, REG_R0, uop->imm_data); - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_mem_store_double); - host_arm_TST_REG(block, REG_R1, REG_R1); - host_arm_BNE(block, (uintptr_t)codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_B(src_size)) - { - host_arm_BFI(block, dest_reg, src_reg, 8, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_arm_VMOV_D_D(block, dest_reg, src_reg); - } - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_arm_MOV_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_arm_MOVW_IMM(block, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x000000ff); - host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size)) - { - host_arm_AND_IMM(block, dest_reg, dest_reg, ~0x0000ff00); - host_arm_ORR_IMM(block, dest_reg, dest_reg, uop->imm_data << 8); - } - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_arm_MOV_IMM(block, uop->dest_reg_a_real, (uintptr_t)uop->p); - - return 0; -} - -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm_SXTB(block, dest_reg, src_reg, 0); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SXTB(block, dest_reg, src_reg, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm_SXTH(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_arm_SXTB(block, REG_TEMP, src_reg, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SXTB(block, REG_TEMP, src_reg, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_IMM(block, REG_TEMP, 0); - host_arm_VMOV_D_64(block, dest_reg, src_reg, REG_TEMP); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_arm_VMOV_32_S(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, dest_reg, src_reg, 0); - } - else if (REG_IS_L(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, dest_reg, src_reg, 8); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, dest_reg, src_reg, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - if (src_reg == dest_reg) - host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_W(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg, 8); - host_arm_BIC_IMM(block, dest_reg, dest_reg, 0xff00); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static double int64_to_double(int64_t a) -{ - return (double)a; -} -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_arm_VMOV_S_32(block, REG_D_TEMP, src_reg); - host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_arm_SXTH(block, REG_TEMP, src_reg, 0); - host_arm_VMOV_S_32(block, REG_D_TEMP, REG_TEMP); - host_arm_VCVT_D_IS(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - /*ARMv7 has no instructions to convert a 64-bit integer to a double. - For simplicity, call a C function and let the compiler do it.*/ - host_arm_VMOV_64_D(block, REG_R0, REG_R1, src_reg); - host_arm_BL(block, (uintptr_t)int64_to_double); /*Input - R0/R1, Output - D0*/ - host_arm_VMOV_D_D(block, dest_reg, REG_D0); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_fp_round); - host_arm_VMOV_32_S(block, dest_reg, REG_D_TEMP); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg); - host_arm_BL(block, (uintptr_t)codegen_fp_round); - host_arm_VMOV_32_S(block, REG_TEMP, REG_D_TEMP); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 15) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int64_t x87_fround64(double b) +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) { - int64_t a, c; + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } - - return 0; -} -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_arm_VMOV_D_D(block, dest_reg, src_64_reg); - host_arm_TST_IMM(block, tag_reg, TAG_UINT64); - branch_offset = host_arm_BNE_(block); - - /*VFP/NEON has no instructions to convert a float to 64-bit integer, - so call out to C.*/ - host_arm_VMOV_D_D(block, REG_D0, src_reg); - host_arm_call(block, x87_fround64); - host_arm_VMOV_D_64(block, REG_D_TEMP, REG_R0, REG_R1); - - *branch_offset |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 8) & 0x3fffffc) >> 2; - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 31) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDR_IMM(block, dest_reg, REG_TEMP, 0); - } + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + if (uop->imm_data == 0) + host_arm_VMOV_D_D(block, dest_reg, src_reg); + else if (uop->imm_data > 63) + host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); + } else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDRB_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size)) - { - host_arm_LDRB_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_arm_MOV_IMM(block, REG_TEMP, (uintptr_t)uop->p); - if (REG_IS_L(dest_size)) - { - host_arm_LDRH_IMM(block, dest_reg, REG_TEMP, 0); - } - else if (REG_IS_W(dest_size)) - { - host_arm_LDRH_IMM(block, REG_TEMP, REG_TEMP, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; + return 0; } -static int codegen_NOP(codeblock_t *block, uop_t *uop) +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) { - return 0; + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); + } else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; } -static int codegen_OR(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VORR_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_ORR_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_ORR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_ORR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; +} +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; +} +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); + if (dest_reg != src_reg_a) + host_arm_VMOV_D_D(block, dest_reg, src_reg_a); + host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + + return 0; } -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +static int +codegen_ROL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_S16(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_S16(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_S32(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_S32(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } else { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); } - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_Q_TEMP, src_reg_a); - host_arm_VMOV_D_D(block, REG_Q_TEMP_2, src_reg_b); - host_arm_VQMOVN_U16(block, dest_reg, REG_Q_TEMP); - host_arm_VQMOVN_U16(block, REG_D_TEMP, REG_Q_TEMP_2); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 16); + } else { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16 - (uop->imm_data & 15)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); } - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I8(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + host_arm_BFI(block, dest_reg, src_reg, 0, 8); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); } - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_U8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQADD_U16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_S32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm_VCVT_S32_F32(block, dest_reg, src_reg_a); - } - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VADD_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCEQ_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGE_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VCGT_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMAX_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMIN_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMUL_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRECPE/VRECPS)*/ - host_arm_VMOV_F32_ONE(block, REG_D_TEMP); - host_arm_VDIV_S(block, dest_reg, REG_D_TEMP, src_reg_a); - host_arm_VDUP_32(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use VRSQRTE/VRSQRTS)*/ - host_arm_VSQRT_S(block, REG_D_TEMP, src_reg_a); - host_arm_VMOV_F32_ONE(block, REG_D_TEMP); - host_arm_VDIV_S(block, dest_reg, dest_reg, REG_D_TEMP); - host_arm_VDUP_32(block, dest_reg, dest_reg, 0); - } - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_F32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_arm_VCVT_F32_S32(block, dest_reg, src_reg_a); - } - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); - - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); - host_arm_VPADDL_Q_S32(block, REG_Q_TEMP, REG_Q_TEMP); - host_arm_VMOVN_I64(block, dest_reg, REG_Q_TEMP); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMULL_S16(block, REG_Q_TEMP, src_reg_a, src_reg_b); - host_arm_VSHRN_32(block, dest_reg, REG_Q_TEMP, 16); - } - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMUL_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHL_D_IMM_64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VSHR_D_S16(block, dest_reg, src_reg, 15); - else - host_arm_VSHR_D_S16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VSHR_D_S32(block, dest_reg, src_reg, 31); - else - host_arm_VSHR_D_S32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VSHR_D_S64(block, dest_reg, src_reg, 63); - else - host_arm_VSHR_D_S64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 15) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U16(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 31) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U32(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - if (uop->imm_data == 0) - host_arm_VMOV_D_D(block, dest_reg, src_reg); - else if (uop->imm_data > 63) - host_arm_VEOR_D(block, dest_reg, dest_reg, dest_reg); - else - host_arm_VSHR_D_U64(block, dest_reg, src_reg, uop->imm_data); - } - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VSUB_I32(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_S8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_S16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_U8(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VQSUB_U16(block, dest_reg, src_reg_a, src_reg_b); - } - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - host_arm_VMOV_D_D(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D8(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D16(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VMOV_D_D(block, REG_D_TEMP, src_reg_b); - if (dest_reg != src_reg_a) - host_arm_VMOV_D_D(block, dest_reg, src_reg_a); - host_arm_VZIP_D32(block, dest_reg, REG_D_TEMP); - } - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 32); - host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, REG_TEMP2); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 16); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_ROR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_RSB_IMM(block, REG_TEMP2, shift_reg, 8); - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP2, REG_TEMP2, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm_MOV_REG(block, dest_reg, src_reg); - } - else - { - host_arm_MOV_REG_ROR(block, dest_reg, src_reg, 32 - (uop->imm_data & 31)); - } - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - host_arm_BFI(block, dest_reg, src_reg, 0, 16); - } - else - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 16-(uop->imm_data & 15)); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - host_arm_BFI(block, dest_reg, src_reg, 0, 8); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8-(uop->imm_data & 7)); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8 - (uop->imm_data & 7)); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR(codeblock_t *block, uop_t *uop) +static int +codegen_ROR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ROR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 15); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_AND_IMM(block, REG_TEMP2, shift_reg, 7); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, REG_TEMP2); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (!(uop->imm_data & 31)) - { - if (src_reg != dest_reg) - host_arm_MOV_REG(block, dest_reg, src_reg); - } - else - { - host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); - } + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (!(uop->imm_data & 31)) { + if (src_reg != dest_reg) + host_arm_MOV_REG(block, dest_reg, src_reg); + } else { + host_arm_MOV_REG_ROR(block, dest_reg, src_reg, uop->imm_data & 31); } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if ((uop->imm_data & 15) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - if ((uop->imm_data & 7) == 0) - { - if (src_reg != dest_reg) - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - } - else - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - } - else + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if ((uop->imm_data & 15) == 0) { + if (src_reg != dest_reg) fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 16); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 15); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + if ((uop->imm_data & 7) == 0) { + if (src_reg != dest_reg) + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + } else { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_ORR_REG_LSL(block, REG_TEMP, REG_TEMP, REG_TEMP, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data & 7); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } + } else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR(codeblock_t *block, uop_t *uop) +static int +codegen_SAR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ASR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); - host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_ASR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTH(block, REG_TEMP, REG_TEMP, 16); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 24); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, 16); + host_arm_MOV_REG_ASR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_UXTB(block, REG_TEMP, REG_TEMP, 24); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL(codeblock_t *block, uop_t *uop) +static int +codegen_SHL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, src_reg, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSL(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_MOV_REG_LSL(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSL(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR(codeblock_t *block, uop_t *uop) +static int +codegen_SHR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSR_REG(block, dest_reg, src_reg, shift_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR_REG(block, REG_TEMP, REG_TEMP, shift_reg); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_UXTH(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_UXTB(block, REG_TEMP, src_reg, 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_MOV_REG_LSR(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_UXTH(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_UXTB(block, REG_TEMP, src_reg, 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) { - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - if (in_range(uop->p, &cpu_state)) - host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + if (in_range(uop->p, &cpu_state)) + host_arm_STR_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) { - host_arm_MOV_IMM(block, REG_R0, uop->imm_data); - if (in_range(uop->p, &cpu_state)) - host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t)uop->p - (uintptr_t)&cpu_state); - else - fatal("codegen_STORE_PTR_IMM - not in range\n"); + host_arm_MOV_IMM(block, REG_R0, uop->imm_data); + if (in_range(uop->p, &cpu_state)) + host_arm_STRB_IMM(block, REG_R0, REG_CPUSTATE, (uintptr_t) uop->p - (uintptr_t) &cpu_state); + else + fatal("codegen_STORE_PTR_IMM - not in range\n"); - return 0; + return 0; } -static int codegen_SUB(codeblock_t *block, uop_t *uop) +static int +codegen_SUB(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) - { - host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) - { - host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); - host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_SUB_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_SUB_REG_LSR(block, REG_TEMP, src_reg_a, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_SUB_REG_LSL(block, REG_TEMP, src_reg_a, src_reg_b, 0); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b)) { + host_arm_RSB_REG_LSR(block, REG_TEMP, src_reg_b, src_reg_a, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b)) { + host_arm_MOV_REG_LSR(block, REG_TEMP, src_reg_a, 8); + host_arm_SUB_REG_LSR(block, REG_TEMP, REG_TEMP, src_reg_b, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; -// host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); -// return 0; + // host_arm_SUB_REG_LSL(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, 0); + // return 0; } -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) - { - host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); - host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); - host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); - } - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_SUB_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 16); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_B(dest_size) && REG_IS_BH(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 0, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size)) { + host_arm_SUB_IMM(block, REG_TEMP, src_reg, uop->imm_data << 8); + host_arm_MOV_REG_LSR(block, REG_TEMP, REG_TEMP, 8); + host_arm_BFI(block, dest_reg, REG_TEMP, 8, 8); + } else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm_BEQ_(block); + uop->p = host_arm_BEQ_(block); - return 0; + return 0; } -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 31); - } - else if (REG_IS_W(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 15); - } - else if (REG_IS_B(src_size)) - { - host_arm_TST_IMM(block, src_reg, 1 << 7); - } - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); + if (REG_IS_L(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 31); + } else if (REG_IS_W(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 15); + } else if (REG_IS_B(src_size)) { + host_arm_TST_IMM(block, src_reg, 1 << 7); + } else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); - uop->p = host_arm_BNE_(block); + uop->p = host_arm_BNE_(block); - return 0; + return 0; } -static int codegen_XOR(codeblock_t *block, uop_t *uop) +static int +codegen_XOR(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) - { - host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); - host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); - } - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_arm_VEOR_D(block, dest_reg, src_reg_a, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, src_reg_b, 0); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTH(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 0); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_B(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 0); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size_a) && REG_IS_BH(src_size_b) && dest_reg == src_reg_a) { + host_arm_UXTB(block, REG_TEMP, src_reg_b, 8); + host_arm_EOR_REG_LSL(block, dest_reg, src_reg_a, REG_TEMP, 8); + } else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - return 0; + return 0; } -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); - } - else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) - { - host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); - } - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data); + } else if (REG_IS_BH(dest_size) && REG_IS_BH(src_size) && dest_reg == src_reg) { + host_arm_EOR_IMM(block, dest_reg, src_reg, uop->imm_data << 8); + } else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); - return 0; + return 0; } -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, - [UOP_JMP & UOP_MASK] = codegen_JMP, + [UOP_JMP & + UOP_MASK] + = codegen_JMP, - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - if (in_range_h(p, &cpu_state)) - host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_8 - not in range\n"); + if (in_range_h(p, &cpu_state)) + host_arm_LDRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_8 - not in range\n"); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - if (in_range_h(p, &cpu_state)) - host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - { - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); - host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); - } + if (in_range_h(p, &cpu_state)) + host_arm_LDRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t) p - (uintptr_t) &cpu_state); + host_arm_LDRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - if (in_range(p, &cpu_state)) - host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_LDR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - codegen_direct_read_32(block, host_reg, p); + codegen_direct_read_32(block, host_reg, p); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VLDR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_LDRB_IMM(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VLDR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - if (in_range(p, &cpu_state)) - host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_8 - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_STRB_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_8 - not in range\n"); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - if (in_range_h(p, &cpu_state)) - host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - { - host_arm_MOV_IMM(block, REG_R3, (uintptr_t)p - (uintptr_t)&cpu_state); - host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); - } + if (in_range_h(p, &cpu_state)) + host_arm_STRH_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else { + host_arm_MOV_IMM(block, REG_R3, (uintptr_t) p - (uintptr_t) &cpu_state); + host_arm_STRH_REG(block, host_reg, REG_CPUSTATE, REG_R3); + } } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - if (in_range(p, &cpu_state)) - host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_32 - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_32 - not in range\n"); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); + host_arm_VSTR_D(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_STRB_IMM(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); - host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); - host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); - host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); - host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t)base - (uintptr_t)&cpu_state); + host_arm_LDR_IMM(block, REG_TEMP, REG_HOST_SP, IREG_TOP_diff_stack_offset); + host_arm_ADD_IMM(block, REG_TEMP, REG_TEMP, reg_idx); + host_arm_AND_IMM(block, REG_TEMP, REG_TEMP, 7); + host_arm_ADD_REG_LSL(block, REG_TEMP, REG_CPUSTATE, REG_TEMP, 3); + host_arm_VSTR_D(block, host_reg, REG_TEMP, (uintptr_t) base - (uintptr_t) &cpu_state); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - if (in_range(p, &cpu_state)) - host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t)p - (uintptr_t)&cpu_state); - else - fatal("codegen_direct_write_ptr - not in range\n"); + if (in_range(p, &cpu_state)) + host_arm_STR_IMM(block, host_reg, REG_CPUSTATE, (uintptr_t) p - (uintptr_t) &cpu_state); + else + fatal("codegen_direct_write_ptr - not in range\n"); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (stack_offset >= 0 && stack_offset < 256) - host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (stack_offset >= 0 && stack_offset < 256) + host_arm_LDRH_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - if (stack_offset >= 0 && stack_offset < 4096) - host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_read_32 - not in range\n"); + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_LDR_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_read_32 - not in range\n"); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - codegen_direct_read_32_stack(block, host_reg, stack_offset); + codegen_direct_read_32_stack(block, host_reg, stack_offset); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VLDR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - if (stack_offset >= 0 && stack_offset < 4096) - host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); - else - fatal("codegen_direct_write_32 - not in range\n"); + if (stack_offset >= 0 && stack_offset < 4096) + host_arm_STR_IMM(block, host_reg, REG_HOST_SP, stack_offset); + else + fatal("codegen_direct_write_32 - not in range\n"); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); + host_arm_VSTR_D(block, host_reg, REG_HOST_SP, stack_offset); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p |= ((((uintptr_t)&block_write_data[block_pos] - (uintptr_t)p) - 8) & 0x3fffffc) >> 2; + *(uint32_t *) p |= ((((uintptr_t) &block_write_data[block_pos] - (uintptr_t) p) - 8) & 0x3fffffc) >> 2; } #endif diff --git a/src/codegen_new/codegen_backend_x86-64.c b/src/codegen_new/codegen_backend_x86-64.c index eadf6b941..a57cb4282 100644 --- a/src/codegen_new/codegen_backend_x86-64.c +++ b/src/codegen_new/codegen_backend_x86-64.c @@ -1,28 +1,28 @@ #if defined __amd64__ || defined _M_X64 -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops.h" -#include "codegen_backend_x86-64_ops_sse.h" -#include "codegen_reg.h" -#include "x86.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops.h" +# include "codegen_backend_x86-64_ops_sse.h" +# include "codegen_reg.h" +# include "x86.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -41,346 +41,338 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - /*Note: while EAX and EDX are normally volatile registers under x86 - calling conventions, the recompiler will explicitly save and restore - them across funcion calls*/ - {REG_EAX, 0}, - {REG_EBX, 0}, - {REG_EDX, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + { REG_EBX, 0}, + { REG_EDX, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ -#if _WIN64 - /*Windows x86-64 calling convention preserves XMM6-XMM15*/ - {REG_XMM6, 0}, - {REG_XMM7, 0}, -#else - /*System V AMD64 calling convention does not preserve any XMM registers*/ - {REG_XMM6, HOST_REG_FLAG_VOLATILE}, - {REG_XMM7, HOST_REG_FLAG_VOLATILE}, -#endif - {REG_XMM1, HOST_REG_FLAG_VOLATILE}, - {REG_XMM2, HOST_REG_FLAG_VOLATILE}, - {REG_XMM3, HOST_REG_FLAG_VOLATILE}, - {REG_XMM4, HOST_REG_FLAG_VOLATILE}, - {REG_XMM5, HOST_REG_FLAG_VOLATILE} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { +# if _WIN64 + /*Windows x86-64 calling convention preserves XMM6-XMM15*/ + {REG_XMM6, 0 }, + { REG_XMM7, 0 }, +# else + /*System V AMD64 calling convention does not preserve any XMM registers*/ + { REG_XMM6, HOST_REG_FLAG_VOLATILE }, + { REG_XMM7, HOST_REG_FLAG_VOLATILE }, +# endif + { REG_XMM1, HOST_REG_FLAG_VOLATILE}, + { REG_XMM2, HOST_REG_FLAG_VOLATILE}, + { REG_XMM3, HOST_REG_FLAG_VOLATILE}, + { REG_XMM4, HOST_REG_FLAG_VOLATILE}, + { REG_XMM5, HOST_REG_FLAG_VOLATILE} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *branch_offset; + uint8_t *misaligned_offset; - /*In - ESI = address - Out - ECX = data, ESI = abrt*/ - /*MOV ECX, ESI - SHR ESI, 12 - MOV RSI, [readlookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOVZX ECX, B[RSI+RCX] - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL readmembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t)(uintptr_t)readlookup2); - host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_ECX, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 2 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); - else if (size == 4 && is_float) - host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else if (size == 8) - host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); - else - fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV RSI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[RSI+RCX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_RDI, (uint64_t) (uintptr_t) readlookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_RDI, REG_RSI, 3); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 2 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_RSI, REG_RCX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else if (size == 8) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_RSI, REG_RCX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_RAX); - host_x86_PUSH(block, REG_RDX); -#if _WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); - //host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); -#else - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); -#endif - if (size == 1 && !is_float) - { - host_x86_CALL(block, (void *)readmembl); - host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - } - else if (size == 2 && !is_float) - { - host_x86_CALL(block, (void *)readmemwl); - host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - } - else if (size == 4 && !is_float) - { - host_x86_CALL(block, (void *)readmemll); - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - } - else if (size == 4 && is_float) - { - host_x86_CALL(block, (void *)readmemll); - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - } - else if (size == 8) - { - host_x86_CALL(block, (void *)readmemql); - host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); - } -#if _WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); -#endif - host_x86_POP(block, REG_RDX); - host_x86_POP(block, REG_RAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); +# if _WIN64 + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x20); + // host_x86_MOV32_REG_REG(block, REG_ECX, uop->imm_data); +# else + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); +# endif + if (size == 1 && !is_float) { + host_x86_CALL(block, (void *) readmembl); + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + } else if (size == 2 && !is_float) { + host_x86_CALL(block, (void *) readmemwl); + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + } else if (size == 4 && !is_float) { + host_x86_CALL(block, (void *) readmemll); + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + } else if (size == 4 && is_float) { + host_x86_CALL(block, (void *) readmemll); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } else if (size == 8) { + host_x86_CALL(block, (void *) readmemql); + host_x86_MOVQ_XREG_REG(block, REG_XMM_TEMP, REG_RAX); + } +# if _WIN64 + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x20); +# endif + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset; + uint8_t *branch_offset; + uint8_t *misaligned_offset; - /*In - ECX = data, ESI = address - Out - ESI = abrt - Corrupts EDI*/ - /*MOV EDI, ESI - SHR ESI, 12 - MOV ESI, [writelookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOV [RSI+RDI], ECX - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL writemembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t)(uintptr_t)writelookup2); - host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_EDI, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); - else if (size == 4 && is_float) - host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else if (size == 8) - host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); - else - fatal("build_store_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [RSI+RDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writemembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV64_REG_IMM(block, REG_R8, (uint64_t) (uintptr_t) writelookup2); + host_x86_MOV64_REG_BASE_INDEX_SHIFT(block, REG_RSI, REG_R8, REG_RSI, 3); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP64_REG_IMM(block, REG_RSI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOV8_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOV16_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_BASE_INDEX_REG(block, REG_RSI, REG_RDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else if (size == 8) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_RSI, REG_RDI, REG_XMM_TEMP); + else + fatal("build_store_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_RAX); - host_x86_PUSH(block, REG_RDX); -#if _WIN64 - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); //data - else if (size == 8) - host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); //data - else - host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); //data - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); //address -#else - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); - //host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); //data - else if (size == 8) - host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); //data - else - host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); //data -#endif - if (size == 1) - host_x86_CALL(block, (void *)writemembl); - else if (size == 2) - host_x86_CALL(block, (void *)writememwl); - else if (size == 4) - host_x86_CALL(block, (void *)writememll); - else if (size == 8) - host_x86_CALL(block, (void *)writememql); -#if _WIN64 - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); -#else - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); -#endif - host_x86_POP(block, REG_RDX); - host_x86_POP(block, REG_RAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + host_x86_PUSH(block, REG_RAX); + host_x86_PUSH(block, REG_RDX); +# if _WIN64 + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x28); + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_EDX, REG_XMM_TEMP); // data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RDX, REG_XMM_TEMP); // data + else + host_x86_MOV32_REG_REG(block, REG_EDX, REG_ECX); // data + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EDI); // address +# else + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x8); + // host_x86_MOV32_REG_REG(block, REG_EDI, REG_ECX); //address + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ESI, REG_XMM_TEMP); // data + else if (size == 8) + host_x86_MOVQ_REG_XREG(block, REG_RSI, REG_XMM_TEMP); // data + else + host_x86_MOV32_REG_REG(block, REG_ESI, REG_ECX); // data +# endif + if (size == 1) + host_x86_CALL(block, (void *) writemembl); + else if (size == 2) + host_x86_CALL(block, (void *) writememwl); + else if (size == 4) + host_x86_CALL(block, (void *) writememll); + else if (size == 8) + host_x86_CALL(block, (void *) writememql); +# if _WIN64 + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x28); +# else + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x8); +# endif + host_x86_POP(block, REG_RDX); + host_x86_POP(block, REG_RAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } -void codegen_backend_init(void) +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); - codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); - block_write_data = codeblock[block_current].data; - build_loadstore_routines(&codeblock[block_current]); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + codeblock[block_current].head_mem_block = codegen_allocator_allocate(NULL, block_current); + codeblock[block_current].data = codeblock_allocator_get_ptr(codeblock[block_current].head_mem_block); + block_write_data = codeblock[block_current].data; + build_loadstore_routines(&codeblock[block_current]); - codegen_gpf_rout = &codeblock[block_current].data[block_pos]; -#if _WIN64 - host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); - host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); -#else - host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); -#endif - host_x86_CALL(block, (void *)x86gpf); - codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; +# if _WIN64 + host_x86_XOR32_REG_REG(block, REG_ECX, REG_ECX); + host_x86_XOR32_REG_REG(block, REG_EDX, REG_EDX); +# else + host_x86_XOR32_REG_REG(block, REG_EDI, REG_EDI); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); +# endif + host_x86_CALL(block, (void *) x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); - block_write_data = NULL; + block_write_data = NULL; - asm( - "stmxcsr %0\n" - : "=m" (cpu_state.old_fp_control) - ); - cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; + asm( + "stmxcsr %0\n" + : "=m"(cpu_state.old_fp_control)); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); } -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; /*Entry code*/ - host_x86_PUSH(block, REG_RBX); - host_x86_PUSH(block, REG_RBP); - host_x86_PUSH(block, REG_RSI); - host_x86_PUSH(block, REG_RDI); - host_x86_PUSH(block, REG_R12); - host_x86_PUSH(block, REG_R13); - host_x86_PUSH(block, REG_R14); - host_x86_PUSH(block, REG_R15); - host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); - host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t)&cpu_state) + 128); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); - } - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t)ram); + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_RBX); + host_x86_PUSH(block, REG_RBP); + host_x86_PUSH(block, REG_RSI); + host_x86_PUSH(block, REG_RDI); + host_x86_PUSH(block, REG_R12); + host_x86_PUSH(block, REG_R13); + host_x86_PUSH(block, REG_R14); + host_x86_PUSH(block, REG_R15); + host_x86_SUB64_REG_IMM(block, REG_RSP, 0x38); + host_x86_MOV64_REG_IMM(block, REG_RBP, ((uintptr_t) &cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, IREG_TOP_diff_stack_offset, REG_EAX); + } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + host_x86_MOV64_REG_IMM(block, REG_R12, (uintptr_t) ram); } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); - host_x86_POP(block, REG_R15); - host_x86_POP(block, REG_R14); - host_x86_POP(block, REG_R13); - host_x86_POP(block, REG_R12); - host_x86_POP(block, REG_RDI); - host_x86_POP(block, REG_RSI); - host_x86_POP(block, REG_RBP); - host_x86_POP(block, REG_RDX); - host_x86_RET(block); + host_x86_ADD64_REG_IMM(block, REG_RSP, 0x38); + host_x86_POP(block, REG_R15); + host_x86_POP(block, REG_R14); + host_x86_POP(block, REG_R13); + host_x86_POP(block, REG_R12); + host_x86_POP(block, REG_RDI); + host_x86_POP(block, REG_RSI); + host_x86_POP(block, REG_RBP); + host_x86_POP(block, REG_RDX); + host_x86_RET(block); } #endif diff --git a/src/codegen_new/codegen_backend_x86-64.h b/src/codegen_new/codegen_backend_x86-64.h index ccc526b30..5f476010d 100644 --- a/src/codegen_new/codegen_backend_x86-64.h +++ b/src/codegen_new/codegen_backend_x86-64.h @@ -1,14 +1,14 @@ #include "codegen_backend_x86-64_defs.h" -#define BLOCK_SIZE 0x4000 -#define BLOCK_MASK 0x3fff +#define BLOCK_SIZE 0x4000 +#define BLOCK_MASK 0x3fff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) -#define BLOCK_MAX 0x3c0 +#define BLOCK_MAX 0x3c0 #define CODEGEN_BACKEND_HAS_MOV_IMM diff --git a/src/codegen_new/codegen_backend_x86-64_defs.h b/src/codegen_new/codegen_backend_x86-64_defs.h index 8955773cd..12f05f01c 100644 --- a/src/codegen_new/codegen_backend_x86-64_defs.h +++ b/src/codegen_new/codegen_backend_x86-64_defs.h @@ -1,52 +1,52 @@ /*RBP = cpu_state + 128 R12 = ram (if block->flags & CODEBLOCK_NO_IMMEDIATES)*/ -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 -#define REG_RAX 0 -#define REG_RCX 1 -#define REG_RDX 2 -#define REG_RBX 3 -#define REG_RSP 4 -#define REG_RBP 5 -#define REG_RSI 6 -#define REG_RDI 7 -#define REG_R8 8 -#define REG_R9 9 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_R13 13 -#define REG_R14 14 -#define REG_R15 15 +#define REG_RAX 0 +#define REG_RCX 1 +#define REG_RDX 2 +#define REG_RBX 3 +#define REG_RSP 4 +#define REG_RBP 5 +#define REG_RSI 6 +#define REG_RDI 7 +#define REG_R8 8 +#define REG_R9 9 +#define REG_R10 10 +#define REG_R11 11 +#define REG_R12 12 +#define REG_R13 13 +#define REG_R14 14 +#define REG_R15 15 -#define REG_XMM0 0 -#define REG_XMM1 1 -#define REG_XMM2 2 -#define REG_XMM3 3 -#define REG_XMM4 4 -#define REG_XMM5 5 -#define REG_XMM6 6 -#define REG_XMM7 7 +#define REG_XMM0 0 +#define REG_XMM1 1 +#define REG_XMM2 2 +#define REG_XMM3 3 +#define REG_XMM4 4 +#define REG_XMM5 5 +#define REG_XMM6 6 +#define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM0 +#define REG_XMM_TEMP REG_XMM0 -#define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_REGS 3 #define CODEGEN_HOST_FP_REGS 7 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_x86-64_ops.c b/src/codegen_new/codegen_backend_x86-64_ops.c index 2baa0f585..33fb500db 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops.c +++ b/src/codegen_new/codegen_backend_x86-64_ops.c @@ -1,1831 +1,1766 @@ #if defined __amd64__ || defined _M_X64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops.h" -#include "codegen_backend_x86-64_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops.h" +# include "codegen_backend_x86-64_ops_helpers.h" -#define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 -#define RM_OP_AND 0x20 -#define RM_OP_SUB 0x28 -#define RM_OP_XOR 0x30 -#define RM_OP_CMP 0x38 +# define RM_OP_ADD 0x00 +# define RM_OP_OR 0x08 +# define RM_OP_AND 0x20 +# define RM_OP_SUB 0x28 +# define RM_OP_XOR 0x30 +# define RM_OP_CMP 0x38 -#define RM_OP_ROL 0x00 -#define RM_OP_ROR 0x08 -#define RM_OP_SHL 0x20 -#define RM_OP_SHR 0x28 -#define RM_OP_SAR 0x38 +# define RM_OP_ROL 0x00 +# define RM_OP_ROR 0x08 +# define RM_OP_SHL 0x20 +# define RM_OP_SHR 0x28 +# define RM_OP_SAR 0x38 -static inline void call(codeblock_t *block, uintptr_t func) +static inline void +call(codeblock_t *block, uintptr_t func) { - intptr_t diff; + intptr_t diff; - codegen_alloc_bytes(block, 5); - diff = (intptr_t)(func - (uintptr_t)&block_write_data[block_pos + 5]); + codegen_alloc_bytes(block, 5); + diff = (intptr_t) (func - (uintptr_t) &block_write_data[block_pos + 5]); - if (diff >= -0x80000000LL && diff < 0x7fffffffLL) - { - codegen_addbyte(block, 0xE8); /*CALL*/ - codegen_addlong(block, (uint32_t)diff); - } - else - { - codegen_alloc_bytes(block, 13); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ - codegen_addquad(block, func); - codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ - } + if (diff >= -0x80000000LL && diff < 0x7fffffffLL) { + codegen_addbyte(block, 0xE8); /*CALL*/ + codegen_addlong(block, (uint32_t) diff); + } else { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xd1); /*CALL R9*/ + } } -static inline void jmp(codeblock_t *block, uintptr_t func) +static inline void +jmp(codeblock_t *block, uintptr_t func) { - intptr_t diff; + intptr_t diff; - codegen_alloc_bytes(block, 5); - diff = (intptr_t)(func - (uintptr_t)&block_write_data[block_pos + 5]); + codegen_alloc_bytes(block, 5); + diff = (intptr_t) (func - (uintptr_t) &block_write_data[block_pos + 5]); - if (diff >= -0x80000000LL && diff < 0x7fffffffLL) - { - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uint32_t)diff); - } - else - { - codegen_alloc_bytes(block, 13); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ - codegen_addquad(block, func); - codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ - } + if (diff >= -0x80000000LL && diff < 0x7fffffffLL) { + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uint32_t) diff); + } else { + codegen_alloc_bytes(block, 13); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, func*/ + codegen_addquad(block, func); + codegen_addbyte3(block, 0x41, 0xff, 0xe1); /*JMP R9*/ + } } -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (dst_reg & 8) - fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); - - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ - } -} -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else - fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); -} -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD8_REG_IMM - dst_reg & 8\n"); + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ -} -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); - + codegen_addbyte2(block, 0x04, imm_data); /*ADD EAX, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data); /*ADD dst_reg, imm_data*/ + } } -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_ADD16_REG_IMM - dst_reg & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ -} - -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); - - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ - } -} -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ -} -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ -} -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ -} - -void host_x86_CALL(codeblock_t *block, void *p) -{ - call(block, (uintptr_t)p); -} - -void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else - fatal("CMP64_REG_IMM not 8-bit imm\n"); -} - -void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} - -void host_x86_JMP(codeblock_t *block, void *p) -{ - jmp(block, (uintptr_t)p); -} - -void host_x86_JNZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} -void host_x86_JZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} - -uint8_t *host_x86_JNZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JS_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block_write_data[block_pos-1]; -} - -uint32_t *host_x86_JNB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_x86_LAHF(codeblock_t *block) -{ - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x9f); /*LAHF*/ -} - -void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) -{ - if (offset) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ - codegen_addlong(block, offset); - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ - } -} -void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG - bad reg\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ - ((src_reg_b & 7) << 3) | (src_reg_a & 7)); -} -void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ - (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); -} - -void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ - codegen_addbyte(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 8); - codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addbyte(block, imm_data); - } -} -void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addword(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 10); - codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addword(block, imm_data); - } -} -void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV8_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV16_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ - codegen_addlong(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - } -} -void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV32_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ - codegen_addlong(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOV64_ABS_REG - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} - -void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} - -void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ -} -void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ -} -void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ -} - -void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOV8_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - fatal("host_x86_MOV8_REG_ABS - out of range\n"); - } -} -void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOV16_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, ram_offset); - } - else - { - fatal("host_x86_MOV16_REG_ABS - out of range\n"); - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 1); - codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ - } -} -void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOV32_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - fatal("host_x86_MOV32_REG_ABS - out of range\n"); - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (dst_reg & 8) - fatal("host_x86_MOV64_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ - codegen_addlong(block, offset); - } - else - fatal("host_x86_MOV64_REG_ABS - out of range\n"); -} - -void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) -{ - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} - -void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) -{ - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ -} - -void host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) -{ - if ((dst_reg & 8) || (index_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - if (base_reg & 8) - codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ - else - codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ -} - -void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if ((dst_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x48); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); -} -void host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if ((src_reg & 8) || (base_reg & 8)) - fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x48); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); -} - -void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) -{ - if (base_reg & 8) - fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); - codegen_addlong(block, imm_data); - } - } - else - fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); -} - -void host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) -{ - if (reg >= 8) - fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ -} -void host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV16_REG_IMM reg & 8\n"); - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addbyte2(block, 0x66, 0x05); /*AND AX, imm_data*/ codegen_addword(block, imm_data); -} -void host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) -{ - if (reg & 8) - fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + } else { codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_ADD32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | (dst_reg & 7)); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_ADD64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_ADD64_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_ADD | (dst_reg & 7), imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else + fatal("ADD64_REG_IMM !is_imm8 %016llx\n", imm_data); +} +void +host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD8_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x00, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ +} +void +host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD16_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ +} +void +host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_ADD32_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x01, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) +void +host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { - if (reg & 8) - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ - codegen_addquad(block, imm_data); - } -} - -void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV8_REG_REG - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND8_REG_IMM - dst_reg & 8\n"); + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); -} -void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV16_REG_REG - bad reg\n"); - + codegen_addbyte2(block, 0x24, imm_data); /*AND EAX, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data); /*AND dst_reg, imm_data*/ + } } -void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOV32_REG_REG - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_AND16_REG_IMM - dst_reg & 8\n"); + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_AND32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | (dst_reg & 7), imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | (dst_reg & 7)); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND8_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x20, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ +} +void +host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND16_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ +} +void +host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_AND32_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x21, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*AND dst_reg, src_reg*/ +} + +void +host_x86_CALL(codeblock_t *block, void *p) +{ + call(block, (uintptr_t) p); +} + +void +host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_CMP64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else + fatal("CMP64_REG_IMM not 8-bit imm\n"); +} + +void +host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} + +void +host_x86_JMP(codeblock_t *block, void *p) +{ + jmp(block, (uintptr_t) p); +} + +void +host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} +void +host_x86_JZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} + +uint8_t * +host_x86_JNZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JS_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block_write_data[block_pos - 1]; +} + +uint32_t * +host_x86_JNB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} + +void +host_x86_LAHF(codeblock_t *block) +{ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x9f); /*LAHF*/ +} + +void +host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) +{ + if (offset) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } else { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } +} +void +host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b]*/ + ((src_reg_b & 7) << 3) | (src_reg_a & 7)); +} +void +host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_LEA_REG_REG_SHIFT - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | ((dst_reg & 7) << 3), /*LEA dst_reg, [Rsrc_reg_a + Rsrc_reg_b * (1 << shift)]*/ + (shift << 6) | ((src_reg_b & 7) << 3) | (src_reg_a & 7)); } -void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +void +host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - if (!offset) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else if (offset >= -0x80 && offset < 0x80) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } -} + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[RBP], imm_data*/ + codegen_addbyte(block, imm_data); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV8_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 8); + codegen_addbyte3(block, 0xc6, 0x04, 0x25); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + codegen_addbyte(block, imm_data); + } } -void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addword(block, imm_data); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 10); + codegen_addbyte4(block, 0x66, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + codegen_addword(block, imm_data); + } } -void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[RBP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_IMM - out of range %p\n", p); + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x04, 0x25); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + codegen_addlong(block, imm_data); + } } -void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +void +host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV8_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x45 | ((src_reg & 7) << 3), offset); /*MOVB offset[RBP], src_reg*/ + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV8_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } +} +void +host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (src_reg & 8) + fatal("host_x86_MOV16_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); + codegen_addbyte4(block, 0x66, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + } } -void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +void +host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) - fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); -} - -void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); - - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + if (src_reg & 8) + fatal("host_x86_MOV32_ABS_REG - bad reg\n"); + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_addbyte3(block, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x89, 0x85 | ((src_reg & 7) << 3)); /*MOV offset[RBP], src_reg*/ + codegen_addlong(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV32_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((src_reg & 7) << 3)); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } -void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV64_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + if (src_reg & 8) + fatal("host_x86_MOV64_ABS_REG - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x89, 0x45 | ((src_reg & 7) << 3), offset); /*MOV offset[RBP], src_reg*/ + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOV64_ABS_REG - out of range %p\n", p); + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x48, 0x89, 0x04 | ((src_reg & 7) << 3), 0x25); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } +} + +void +host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int index_reg, int shift, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + +void +host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV B[base_reg + index_reg], src_reg*/ +} +void +host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV W[base_reg + index_reg], src_reg*/ +} +void +host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int index_reg, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_BASE_INDEX_REG reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), (index_reg << 3) | base_reg); /*MOV L[base_reg + index_reg], src_reg*/ +} + +void +host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + if (dst_reg & 8) + fatal("host_x86_MOV8_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_addbyte3(block, 0x8a, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8a, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8a, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV8_REG_ABS - out of range\n"); + } } - -void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) +void +host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); + if (dst_reg & 8) + fatal("host_x86_MOV16_REG_ABS reg & 8\n"); - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x66, 0x41); - codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } -} -void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - -// if (dst_reg & 8) -// fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - if (dst_reg & 8) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x44); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - - codegen_alloc_bytes(block, 9); - codegen_addbyte(block, 0x41); - codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); - - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } -} -void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) -{ - int64_t offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - int64_t ram_offset = (uintptr_t)p - (uintptr_t)ram; - - if (dst_reg & 8) - fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ - } - else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) - { - codegen_alloc_bytes(block, 9); - codegen_addbyte(block, 0x41); - codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ - codegen_addlong(block, ram_offset); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ - codegen_addquad(block, (uintptr_t)p); - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ - } -} - -void host_x86_NOP(codeblock_t *block) -{ + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3)); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV16_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x90); /*NOP*/ + codegen_addbyte4(block, 0x66, 0x41, 0x8b, 0x01 | ((dst_reg & 7) << 3)); /*MOV dst_reg, [r9]*/ + } } - -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - if (dst_reg & 8) - fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ - } -} -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ -} -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + if (dst_reg & 8) + fatal("host_x86_MOV32_REG_ABS reg & 8\n"); + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + codegen_addbyte3(block, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x41, 0x8b, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOV dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + fatal("host_x86_MOV32_REG_ABS - out of range\n"); + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | ((dst_reg & 7) << 3)); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV64_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ + if (dst_reg & 8) + fatal("host_x86_MOV64_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x8b, 0x45 | ((dst_reg & 7) << 3), offset); /*MOV dst_reg, offset[RBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x48, 0x8b, 0x85 | ((dst_reg & 7) << 3)); /*MOV dst_reg, offset[RBP]*/ + codegen_addlong(block, offset); + } else + fatal("host_x86_MOV64_REG_ABS - out of range\n"); } -void host_x86_POP(codeblock_t *block, int dst_reg) +void +host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int index_reg, int shift) { + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV8_REG_ABS_REG_REG_SHIFT reg & 8\n"); + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (index_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } +} + +void +host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_INDEX reg & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); /*MOV dst_reg, Q[base_reg + index_reg]*/ +} + +void +host_x86_MOV64_REG_BASE_INDEX_SHIFT(codeblock_t *block, int dst_reg, int base_reg, int index_reg, int scale) +{ + if ((dst_reg & 8) || (index_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_INDEX_SHIFT reg & 8\n"); + codegen_alloc_bytes(block, 4); + if (base_reg & 8) + codegen_addbyte4(block, 0x49, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ + else + codegen_addbyte4(block, 0x48, 0x8b, 0x04 | ((dst_reg & 7) << 3), (scale << 6) | ((index_reg & 7) << 3) | (base_reg & 7)); /*MOV dst_reg, Q[base_reg + index_reg << scale]*/ +} + +void +host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV16_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV32_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOV64_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if ((dst_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_REG_BASE_OFFSET reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} + +void +host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV32_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); +} +void +host_x86_MOV64_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if ((src_reg & 8) || (base_reg & 8)) + fatal("host_x86_MOV64_BASE_OFFSET_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x48); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x48, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV64_BASE_OFFSET_REG - offset %i\n", offset); +} + +void +host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) +{ + if (base_reg & 8) + fatal("host_x86_MOV32_BASE_OFFSET_IMM reg & 8\n"); + + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); +} + +void +host_x86_MOV8_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg >= 8) + fatal("host_x86_MOV8_REG_IMM reg >= 4\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xb0 | reg, imm_data); /*MOV reg, imm_data*/ +} +void +host_x86_MOV16_REG_IMM(codeblock_t *block, int reg, uint16_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV16_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); +} +void +host_x86_MOV32_REG_IMM(codeblock_t *block, int reg, uint32_t imm_data) +{ + if (reg & 8) + fatal("host_x86_MOV32_REG_IMM reg & 8\n"); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xb8 | (reg & 7)); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); +} + +void +host_x86_MOV64_REG_IMM(codeblock_t *block, int reg, uint64_t imm_data) +{ + if (reg & 8) { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x48, 0xb8 | (reg & 7)); /*MOVQ reg, imm_data*/ + codegen_addquad(block, imm_data); + } +} + +void +host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV8_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x88, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +void +host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV16_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} +void +host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOV32_REG_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x89, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); +} + +void +host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) +{ + if (!offset) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } +} + +void +host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} + +void +host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_8 reg & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); +} +void +host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int index_reg) +{ + if ((dst_reg & 8) || (base_reg & 8) | (index_reg & 8)) + fatal("host_x86_MOVZX_BASE_INDEX_32_16 reg & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), (index_reg << 3) | base_reg); +} + +void +host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_MOVZX_REG_16_8 - bad reg\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +void +host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_16_8 - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x66, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } +} +void +host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + // if (dst_reg & 8) + // fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + if (offset >= -128 && offset < 127) { + if (dst_reg & 8) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x44); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { if (dst_reg & 8) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ - } - else - { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ - } + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb6, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_8 - bad reg\n"); + + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb6, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } +} +void +host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) +{ + int64_t offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + int64_t ram_offset = (uintptr_t) p - (uintptr_t) ram; + + if (dst_reg & 8) + fatal("host_x86_MOVZX_REG_ABS_32_16 - bad reg\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | ((dst_reg & 7) << 3), offset); /*MOVZX dst_reg, offset[RBP]*/ + } else if ((ram_offset < (1ull << 32)) && (block->flags & CODEBLOCK_NO_IMMEDIATES)) { + codegen_alloc_bytes(block, 9); + codegen_addbyte(block, 0x41); + codegen_addbyte4(block, 0x0f, 0xb7, 0x84 | ((dst_reg & 7) << 3), 0x24); /*MOVZX dst_reg, ram_offset[R12]*/ + codegen_addlong(block, ram_offset); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0x49, 0xb9); /*MOV R9, p*/ + codegen_addquad(block, (uintptr_t) p); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x41, 0x0f, 0xb7, 0x01 | ((dst_reg & 7) << 3)); /*MOVZX dst_reg, [r9]*/ + } } -void host_x86_PUSH(codeblock_t *block, int src_reg) +void +host_x86_NOP(codeblock_t *block) { - if (src_reg & 8) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ - } - else - { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ - } + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x90); /*NOP*/ } -void host_x86_RET(codeblock_t *block) +void +host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + if (dst_reg & 8) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x0c, imm_data); /*OR EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data); /*OR dst_reg, imm_data*/ + } +} +void +host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | (dst_reg & 7), imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | (dst_reg & 7)); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} +void +host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR8_REG_IMM - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x08, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ +} +void +host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR16_REG_IMM - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ +} +void +host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_OR32_REG_IMM - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x09, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*OR dst_reg, src_reg*/ +} + +void +host_x86_POP(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x41, 0x58 | (dst_reg & 7)); /*POP reg*/ + } else { codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0xc3); /*RET*/ + codegen_addbyte(block, 0x58 | dst_reg); /*POP reg*/ + } } -void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) +void +host_x86_PUSH(codeblock_t *block, int src_reg) { - if (dst_reg & 8) - fatal("ROL8 CL & 8\n"); + if (src_reg & 8) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROL16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROL32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + codegen_addbyte2(block, 0x41, 0x50 | (src_reg & 7)); /*PUSH reg*/ + } else { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + } } -void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_RET(codeblock_t *block) { - if (dst_reg & 8) - fatal("ROL8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0xc3); /*RET*/ } -void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) + +void +host_x86_ROL8_CL(codeblock_t *block, int dst_reg) { - if (dst_reg & 8) - fatal("ROL16 imm & 8\n"); + if (dst_reg & 8) + fatal("ROL8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROL32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROL32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_ROR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR8 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR16 CL & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("ROR32 CL & 8\n"); + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR8 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR16 imm & 8\n"); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("ROR32 im & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void +host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SAR32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} + +void +host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SAR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} + +void +host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHL32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHL32 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_SHR8_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR8 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR16_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR16 CL & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR32_CL(codeblock_t *block, int dst_reg) +{ + if (dst_reg & 8) + fatal("SHR32 CL & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR8 imm & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR16 imm & 8\n"); + + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + if (dst_reg & 8) + fatal("SHR32 imm & 8\n"); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void +host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); + + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ + } +} +void +host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("ROL32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} - -void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROR8 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROR16 CL & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("ROR32 CL & 8\n"); - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("ROR8 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("ROR16 imm & 8\n"); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("ROR32 im & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } - -void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +void +host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) { - if (dst_reg & 8) - fatal("SAR8 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} -void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SAR16 CL & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} -void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SAR32 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} - -void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SAR8 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ -} -void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SAR16 imm & 8\n"); + if (dst_reg & 8) + fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else + fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); } -void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("SAR32 imm & 8\n"); - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ +} +void +host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ +} +void +host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHL8 CL & 8\n"); +# define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) +void +host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) +{ + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_TEST32_REG - bad reg\n"); + + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg & 8) + fatal("TEST32_REG_IMM reg & 8\n"); + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg & 8) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); + + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHL16 CL & 8\n"); - + codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ + } } -void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +void +host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - if (dst_reg & 8) - fatal("SHL32 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} - -void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHL8 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHL16 imm & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHL32 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} - -void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHR8 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHR16 CL & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) -{ - if (dst_reg & 8) - fatal("SHR32 CL & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHR8 imm & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ - if (dst_reg & 8) - fatal("SHR16 imm & 8\n"); - + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { - if (dst_reg & 8) - fatal("SHR32 imm & 8\n"); + if (dst_reg & 8) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); + + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } - -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("host_x86_SUB8_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x2c, imm_data); /*SUB EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data); /*SUB dst_reg, imm_data*/ - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +void +host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("host_x86_SUB16_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +void +host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg & 8) - fatal("host_x86_SUB32_REG_IMM - dst_reg & 8\n"); + if ((dst_reg & 8) || (src_reg & 8)) + fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | (dst_reg & 7)); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_SUB64_REG_IMM(codeblock_t *block, int dst_reg, uint64_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_SUB64_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x48, 0x83, 0xc0 | RM_OP_SUB | (dst_reg & 7), imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else - fatal("SUB64_REG_IMM !is_imm8 %016llx\n", imm_data); -} -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB8_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ -} -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB16_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ -} -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_SUB32_REG_REG - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*SUB dst_reg, src_reg*/ -} - -#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) - -void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG(codeblock_t *block, int src_reg, int dst_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_TEST32_REG - bad reg\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_reg, src_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("TEST32_REG_IMM reg & 8\n"); - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x34, imm_data); /*XOR EAX, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data); /*XOR dst_reg, imm_data*/ - } -} -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg & 8) - fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | (dst_reg & 7), imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | (dst_reg & 7)); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR8_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR16_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - if ((dst_reg & 8) || (src_reg & 8)) - fatal("host_x86_XOR32_REG_IMM - dst_reg & 8\n"); - - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); /*XOR dst_reg, src_reg*/ } #endif diff --git a/src/codegen_new/codegen_backend_x86-64_ops_helpers.h b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h index a7755d1a8..42c2d5259 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops_helpers.h +++ b/src/codegen_new/codegen_backend_x86-64_ops_helpers.h @@ -1,102 +1,103 @@ #define JMP_LEN_BYTES 5 -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +static inline void +codegen_addbyte(codeblock_t *block, uint8_t val) { - if (block_pos >= BLOCK_MAX) - { - fatal("codegen_addbyte over! %i\n", block_pos); -// CPU_BLOCK_END(); - } - block_write_data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) { + fatal("codegen_addbyte over! %i\n", block_pos); + // CPU_BLOCK_END(); + } + block_write_data[block_pos++] = val; } -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +static inline void +codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { - if (block_pos > (BLOCK_MAX-2)) - { - fatal("codegen_addbyte2 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; + if (block_pos > (BLOCK_MAX - 2)) { + fatal("codegen_addbyte2 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; } -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +static inline void +codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { - if (block_pos > (BLOCK_MAX-3)) - { - fatal("codegen_addbyte3 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; + if (block_pos > (BLOCK_MAX - 3)) { + fatal("codegen_addbyte3 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; } -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +static inline void +codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { - if (block_pos > (BLOCK_MAX-4)) - { - fatal("codegen_addbyte4 over! %i\n", block_pos); - CPU_BLOCK_END(); - } - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; - block_write_data[block_pos++] = vald; + if (block_pos > (BLOCK_MAX - 4)) { + fatal("codegen_addbyte4 over! %i\n", block_pos); + CPU_BLOCK_END(); + } + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; } -static inline void codegen_addword(codeblock_t *block, uint16_t val) +static inline void +codegen_addword(codeblock_t *block, uint16_t val) { - if (block_pos > (BLOCK_MAX-2)) - { - fatal("codegen_addword over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint16_t *)&block_write_data[block_pos] = val; - block_pos += 2; + if (block_pos > (BLOCK_MAX - 2)) { + fatal("codegen_addword over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint16_t *) &block_write_data[block_pos] = val; + block_pos += 2; } -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos > (BLOCK_MAX-4)) - { - fatal("codegen_addlong over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos > (BLOCK_MAX - 4)) { + fatal("codegen_addlong over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static inline void codegen_addquad(codeblock_t *block, uint64_t val) +static inline void +codegen_addquad(codeblock_t *block, uint64_t val) { - if (block_pos > (BLOCK_MAX-8)) - { - fatal("codegen_addquad over! %i\n", block_pos); - CPU_BLOCK_END(); - } - *(uint64_t *)&block_write_data[block_pos] = val; - block_pos += 8; + if (block_pos > (BLOCK_MAX - 8)) { + fatal("codegen_addquad over! %i\n", block_pos); + CPU_BLOCK_END(); + } + *(uint64_t *) &block_write_data[block_pos] = val; + block_pos += 8; } -static inline void codegen_alloc_bytes(codeblock_t *block, int size) +static inline void +codegen_alloc_bytes(codeblock_t *block, int size) { - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) { + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - /*Add a jump instruction to the new block*/ - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos + 4]); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; - } + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; + } } -static inline int is_imm8(uint32_t imm_data) +static inline int +is_imm8(uint32_t imm_data) { - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; } diff --git a/src/codegen_new/codegen_backend_x86-64_ops_sse.c b/src/codegen_new/codegen_backend_x86-64_ops_sse.c index e2a4e7044..f15b1aee4 100644 --- a/src/codegen_new/codegen_backend_x86-64_ops_sse.c +++ b/src/codegen_new/codegen_backend_x86-64_ops_sse.c @@ -1,618 +1,678 @@ #if defined __amd64__ || defined _M_X64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops_sse.h" -#include "codegen_backend_x86-64_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops_sse.h" +# include "codegen_backend_x86-64_ops_helpers.h" -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ +} + +void +host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); +} + +void +host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ +} +void +host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ +} + +void +host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ +} +void +host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} +void +host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void +host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ +} +void +host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); +} +void +host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void +host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); +} +void +host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} + +void +host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } else if (offset < (1ull << 32)) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ + codegen_addlong(block, offset); + } else { + fatal("host_x86_LDMXCSR - out of range %p\n", p); + } } -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +void +host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ } -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +void +host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void +host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ -} -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ -} -void host_x86_CVTSD2SI_REG64_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ + if (src_reg & 8) + fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2d); /*CVTSD2SI dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ -} -void host_x86_CVTSI2SD_XREG_REG64(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf2, 0x48, 0x0f, 0x2a); /*CVTSI2SD dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); -} -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ -} - -void host_x86_LDMXCSR(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } - else if (offset < (1ull << 32)) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x90 | REG_EBP); /*LDMXCSR offset[EBP]*/ - codegen_addlong(block, offset); - } - else - { - fatal("host_x86_LDMXCSR - out of range %p\n", p); - } -} - -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ -} - -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (src_reg & 8) - fatal("host_x86_MOVQ_ABS_REG reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) -{ - if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); - - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} - -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_RSP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); -} - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (dst_reg & 8) - fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - if ((uintptr_t)p >> 32) - fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addbyte(block, 0x25); - codegen_addlong(block, (uint32_t)(uintptr_t)p); - } -} -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) -{ - if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) - fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); - - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ -} - -void host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ - codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ -} -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ -} - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ -} -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOVQ_ABS_REG - out of range %p\n", p); codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { + if ((src_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_ABS_REG_REG_SHIFT_REG - bad reg\n"); + + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_RSP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [RSP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} + +void +host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (dst_reg & 8) + fatal("host_x86_MOVQ_REG_ABS reg & 8\n"); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + if ((uintptr_t) p >> 32) + fatal("host_x86_MOVQ_REG_ABS - out of range %p\n", p); codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addbyte(block, 0x25); + codegen_addlong(block, (uint32_t) (uintptr_t) p); + } } +void +host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if ((dst_reg & 8) || (src_reg_a & 8) || (src_reg_b & 8)) + fatal("host_x86_MOVQ_REG_ABS_REG_REG_SHIFT - bad reg\n"); -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ -} -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ -} -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ -} -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ -} - -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ -} -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ -} -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ -} -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ -} - -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ -} -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ -} -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ -} -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ -} -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ -} -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ -} - -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ -} - -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} - -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ -} -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ -} -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ -} -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ -} -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ -} - -void host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } -void host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); } -void host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, 0xee); -} -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ -} -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ -} -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); } -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ -} -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x7e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x48, 0x0f, 0x6e); /*MOVQ dst_reg, src_reg*/ + codegen_addbyte(block, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ +} +void +host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ +} + +void +host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ +} +void +host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void +host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} +void +host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); +} + +void +host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void +host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void +host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void +host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void +host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void +host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ +} + +void +host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void +host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void +host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void +host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ +} + +void +host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ +} +void +host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ +} +void +host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ +} +void +host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ +} +void +host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ +} +void +host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ +} + +void +host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void +host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} +void +host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ +} + +void +host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} + +void +host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ +} +void +host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void +host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void +host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void +host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void +host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ +} + +void +host_x86_PUNPCKHBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void +host_x86_PUNPCKHWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void +host_x86_PUNPCKHDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, 0xee); +} +void +host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + +void +host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} +void +host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} + +void +host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} +void +host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } #endif diff --git a/src/codegen_new/codegen_backend_x86-64_uops.c b/src/codegen_new/codegen_backend_x86-64_uops.c index 9997ea738..e9c08cbc8 100644 --- a/src/codegen_new/codegen_backend_x86-64_uops.c +++ b/src/codegen_new/codegen_backend_x86-64_uops.c @@ -1,3165 +1,3280 @@ #if defined __amd64__ || defined _M_X64 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x87.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_backend.h" -#include "codegen_backend_x86-64_defs.h" -#include "codegen_backend_x86-64_ops.h" -#include "codegen_backend_x86-64_ops_sse.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x87.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_backend.h" +# include "codegen_backend_x86-64_defs.h" +# include "codegen_backend_x86-64_ops.h" +# include "codegen_backend_x86-64_ops_sse.h" +# include "codegen_ir_defs.h" -#define STACK_ARG0 (0) -#define STACK_ARG1 (4) -#define STACK_ARG2 (8) -#define STACK_ARG3 (12) +# define STACK_ARG0 (0) +# define STACK_ARG1 (4) +# define STACK_ARG2 (8) +# define STACK_ARG3 (12) -#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) +# define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) &3) | 4) : (IREG_GET_REG(reg) & 7)) -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) +static int +codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); - else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); - else - host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - if (!uop->imm_data) - { - if (uop->dest_reg_a_real == uop->src_reg_a_real) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); - else - host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - } - else if (uop->imm_data < 4) - host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); -#ifdef RECOMPILER_DEBUG + if (!uop->imm_data) { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); else - fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); -#endif - return 0; + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); +# endif + return 0; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +static int +codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ANDN(codeblock_t *block, uop_t *uop) +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); + host_x86_CALL(block, uop->p); - return 0; + return 0; } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); -#endif - host_x86_CALL(block, uop->p); - host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); +# endif + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); -#endif - host_x86_JZ(block, uop->p); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); +# endif + host_x86_JZ(block, uop->p); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JB_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JNBE_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNB_long(block); - return 0; + return 0; } -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNL_long(block); - return 0; + return 0; } -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNO_long(block); - return 0; + return 0; } -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JB_long(block); - return 0; + return 0; } -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JL_long(block); - return 0; + return 0; } -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JO_long(block); - return 0; + return 0; } -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); - host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_FTST(codeblock_t *block, uop_t *uop) +static int +codegen_FTST(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_FADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FCOM(codeblock_t *block, uop_t *uop) +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FDIV(codeblock_t *block, uop_t *uop) +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_offset; - - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, 7); -#else - host_x86_MOV32_REG_IMM(block, REG_EDI, 7); -#endif - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - - return 0; -} -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) -{ - uint32_t *branch_offset; - - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, 7); -#else - host_x86_MOV32_REG_IMM(block, REG_EDI, 7); -#endif - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); - host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); - - return 0; -} - -static int codegen_JMP(codeblock_t *block, uop_t *uop) -{ - host_x86_JMP(block, uop->p); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { -#if _WIN64 - host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); -#else - host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); -#endif - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); -#else - host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ -#if _WIN64 - host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); -#else - host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); -#endif - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); -#endif -#if _WIN64 - host_x86_MOV16_REG_REG(block, REG_CX, src_reg); - host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t)uop->p); -#else - host_x86_MOV16_REG_REG(block, REG_DI, src_reg); - host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t)uop->p); -#endif - host_x86_CALL(block, (void *)loadseg); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - - return 0; -} -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } - - return 0; -} -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *branch_offset; - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); +# endif + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; - return 0; + return 0; +} +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +{ + uint32_t *branch_offset; + + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, 7); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, 7); +# endif + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + + return 0; } -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +static int +codegen_JMP(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + host_x86_JMP(block, uop->p); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(src_size)) { +# if _WIN64 + host_x86_MOVZX_REG_32_16(block, REG_ECX, src_reg); +# else + host_x86_MOVZX_REG_32_16(block, REG_EDI, src_reg); +# endif + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) +{ +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); +# else + host_x86_MOV32_REG_IMM(block, REG_EDI, uop->imm_data); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) +{ +# if _WIN64 + host_x86_MOV32_REG_IMM(block, REG_EDX, uop->imm_data); +# else + host_x86_MOV32_REG_IMM(block, REG_ESI, uop->imm_data); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG2_IMM\n"); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG3_IMM\n"); +# endif + return 0; +} + +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +# endif +# if _WIN64 + host_x86_MOV16_REG_REG(block, REG_CX, src_reg); + host_x86_MOV64_REG_IMM(block, REG_EDX, (uint64_t) uop->p); +# else + host_x86_MOV16_REG_REG(block, REG_DI, src_reg); + host_x86_MOV64_REG_IMM(block, REG_ESI, (uint64_t) uop->p); +# endif + host_x86_CALL(block, (void *) loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_x86_CALL(block, codegen_mem_load_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_Q(dest_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } + + return 0; +} +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; +} + +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_byte); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_word); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; +} +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; } -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t)uop->p); - return 0; -} -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); - host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); - host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_long(block); - - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); - - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_NOP(codeblock_t *block, uop_t *uop) -{ - return 0; -} - -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); - host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RCPSS + iteration)*/ - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RSQRTSS + iteration)*/ - host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - if (((uintptr_t)uop->p) >> 32) - fatal("STORE_PTR_IMM 64-bit addr\n"); -#endif - host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - if (((uintptr_t)uop->p) >> 32) - fatal("STORE_PTR_IMM_8 64-bit addr\n"); -#endif - host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} - -static int codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (dest_reg != src_reg_a) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNS_long(block); - - return 0; -} -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JS_long(block); - - return 0; -} - -static int codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - - [UOP_JMP & UOP_MASK] = codegen_JMP, - - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, - - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP + host_x86_CALL(block, codegen_mem_store_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MOV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV64_REG_IMM(block, uop->dest_reg_a_real, (uint64_t) uop->p); + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_REG_XREG(block, REG_RCX, src_reg); + host_x86_CVTSI2SD_XREG_REG64(block, dest_reg, REG_RCX); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_long(block); + + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG64_XREG(block, REG_RCX, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + host_x86_MOVQ_XREG_REG(block, dest_reg, REG_RCX); + + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKHDQ_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + if (((uintptr_t) uop->p) >> 32) + fatal("STORE_PTR_IMM 64-bit addr\n"); +# endif + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + if (((uintptr_t) uop->p) >> 32) + fatal("STORE_PTR_IMM_8 64-bit addr\n"); +# endif + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} + +static int +codegen_SUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (dest_reg != src_reg_a) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNS_long(block); + + return 0; +} +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JS_long(block); + + return 0; +} + +static int +codegen_XOR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & + UOP_MASK] + = codegen_JMP, + + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, + + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, + + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, + + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, + + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, + + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, + + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, + + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, + + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, + + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, + + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, + + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, + + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, + + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, + + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, + + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, + + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, + + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, + + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, + + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV8_REG_ABS(block, host_reg, p); + host_x86_MOV8_REG_ABS(block, host_reg, p); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV16_REG_ABS(block, host_reg, p); + host_x86_MOV16_REG_ABS(block, host_reg, p); } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV32_REG_ABS(block, host_reg, p); + host_x86_MOV32_REG_ABS(block, host_reg, p); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV64_REG_ABS(block, host_reg, p); + host_x86_MOV64_REG_ABS(block, host_reg, p); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 0); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_RBP, REG_ECX, 3); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV8_ABS_REG(block, p, host_reg); + host_x86_MOV8_ABS_REG(block, p, host_reg); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV16_ABS_REG(block, p, host_reg); + host_x86_MOV16_ABS_REG(block, p, host_reg); } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); + host_x86_MOV32_ABS_REG(block, p, host_reg); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_pointer(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV64_ABS_REG(block, p, host_reg); + host_x86_MOV64_ABS_REG(block, p, host_reg); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_RBP, REG_ECX, 0, host_reg); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_RSP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_RBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV64_ABS_REG(block, p, host_reg); + host_x86_MOV64_ABS_REG(block, p, host_reg); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOV64_REG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_RSP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } -void codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_pointer_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOV64_BASE_OFFSET_REG(block, REG_RSP, stack_offset, host_reg); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_RSP, stack_offset, host_reg); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *) p = (uintptr_t) &block_write_data[block_pos] - ((uintptr_t) p + 4); } -void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) +void +codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { - host_x86_MOV8_ABS_IMM(block, p, imm_data); + host_x86_MOV8_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) +void +codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { - host_x86_MOV16_ABS_IMM(block, p, imm_data); + host_x86_MOV16_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) +void +codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { - host_x86_MOV32_ABS_IMM(block, p, imm_data); + host_x86_MOV32_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) +void +codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) { - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); } #endif diff --git a/src/codegen_new/codegen_backend_x86.c b/src/codegen_new/codegen_backend_x86.c index 03c9b2a34..2de794ad1 100644 --- a/src/codegen_new/codegen_backend_x86.c +++ b/src/codegen_new/codegen_backend_x86.c @@ -1,29 +1,29 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops.h" -#include "codegen_backend_x86_ops_sse.h" -#include "codegen_reg.h" -#include "x86.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops.h" +# include "codegen_backend_x86_ops_sse.h" +# include "codegen_reg.h" +# include "x86.h" -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#if defined WIN32 || defined _WIN32 || defined _WIN32 -#include -#endif -#include +# if defined(__linux__) || defined(__APPLE__) +# include +# include +# endif +# if defined WIN32 || defined _WIN32 || defined _WIN32 +# include +# endif +# include void *codegen_mem_load_byte; void *codegen_mem_load_word; @@ -42,306 +42,303 @@ void *codegen_mem_store_double; void *codegen_gpf_rout; void *codegen_exit_rout; -host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = -{ - /*Note: while EAX and EDX are normally volatile registers under x86 - calling conventions, the recompiler will explicitly save and restore - them across funcion calls*/ - {REG_EAX, 0}, - {REG_EBX, 0}, - {REG_EDX, 0} +host_reg_def_t codegen_host_reg_list[CODEGEN_HOST_REGS] = { + /*Note: while EAX and EDX are normally volatile registers under x86 + calling conventions, the recompiler will explicitly save and restore + them across funcion calls*/ + {REG_EAX, 0}, + { REG_EBX, 0}, + { REG_EDX, 0} }; -host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = -{ - {REG_XMM0, HOST_REG_FLAG_VOLATILE}, - {REG_XMM1, HOST_REG_FLAG_VOLATILE}, - {REG_XMM2, HOST_REG_FLAG_VOLATILE}, - {REG_XMM3, HOST_REG_FLAG_VOLATILE}, - {REG_XMM4, HOST_REG_FLAG_VOLATILE}, - {REG_XMM5, HOST_REG_FLAG_VOLATILE} +host_reg_def_t codegen_host_fp_reg_list[CODEGEN_HOST_FP_REGS] = { + {REG_XMM0, HOST_REG_FLAG_VOLATILE}, + { REG_XMM1, HOST_REG_FLAG_VOLATILE}, + { REG_XMM2, HOST_REG_FLAG_VOLATILE}, + { REG_XMM3, HOST_REG_FLAG_VOLATILE}, + { REG_XMM4, HOST_REG_FLAG_VOLATILE}, + { REG_XMM5, HOST_REG_FLAG_VOLATILE} }; -static void build_load_routine(codeblock_t *block, int size, int is_float) +static void +build_load_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset = NULL; + uint8_t *branch_offset; + uint8_t *misaligned_offset = NULL; - /*In - ESI = address - Out - ECX = data, ESI = abrt*/ - /*MOV ECX, ESI - SHR ESI, 12 - MOV ESI, [readlookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOVZX ECX, B[ESI+ECX] - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL readmembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_ECX, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); - else if (size == 4 && is_float) - host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else if (size == 8) - host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); - else - fatal("build_load_routine: size=%i\n", size); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ESI = address + Out - ECX = data, ESI = abrt*/ + /*MOV ECX, ESI + SHR ESI, 12 + MOV ESI, [readlookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOVZX ECX, B[ESI+ECX] + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL readmembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_ECX, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, readlookup2, REG_ESI, 2); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_ECX, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_8(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOVZX_BASE_INDEX_32_16(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_BASE_INDEX(block, REG_ECX, REG_ESI, REG_ECX); + else if (size == 4 && is_float) + host_x86_CVTSS2SD_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else if (size == 8) + host_x86_MOVQ_XREG_BASE_INDEX(block, REG_XMM_TEMP, REG_ESI, REG_ECX); + else + fatal("build_load_routine: size=%i\n", size); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - host_x86_PUSH(block, REG_EAX); - host_x86_PUSH(block, REG_EDX); - host_x86_PUSH(block, REG_ECX); - if (size == 1) - host_x86_CALL(block, (void *)readmembl); - else if (size == 2) - host_x86_CALL(block, (void *)readmemwl); - else if (size == 4) - host_x86_CALL(block, (void *)readmemll); - else if (size == 8) - host_x86_CALL(block, (void *)readmemql); - host_x86_POP(block, REG_ECX); - if (size == 1 && !is_float) - host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); - else if (size == 2 && !is_float) - host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); - else if (size == 4 && !is_float) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - else if (size == 4 && is_float) - { - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - } - else if (size == 8) - { - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); - host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); - host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); - } - host_x86_POP(block, REG_EDX); - host_x86_POP(block, REG_EAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 1) + host_x86_CALL(block, (void *) readmembl); + else if (size == 2) + host_x86_CALL(block, (void *) readmemwl); + else if (size == 4) + host_x86_CALL(block, (void *) readmemll); + else if (size == 8) + host_x86_CALL(block, (void *) readmemql); + host_x86_POP(block, REG_ECX); + if (size == 1 && !is_float) + host_x86_MOVZX_REG_32_8(block, REG_ECX, REG_EAX); + else if (size == 2 && !is_float) + host_x86_MOVZX_REG_32_16(block, REG_ECX, REG_EAX); + else if (size == 4 && !is_float) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + else if (size == 4 && is_float) { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_CVTSS2SD_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + } else if (size == 8) { + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP, REG_EAX); + host_x86_MOVD_XREG_REG(block, REG_XMM_TEMP2, REG_EDX); + host_x86_UNPCKLPS_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP2); + } + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; } -static void build_store_routine(codeblock_t *block, int size, int is_float) +static void +build_store_routine(codeblock_t *block, int size, int is_float) { - uint8_t *branch_offset; - uint8_t *misaligned_offset = NULL; + uint8_t *branch_offset; + uint8_t *misaligned_offset = NULL; - /*In - ECX = data, ESI = address - Out - ESI = abrt - Corrupts EDI*/ - /*MOV EDI, ESI - SHR ESI, 12 - MOV ESI, [writelookup2+ESI*4] - CMP ESI, -1 - JNZ + - MOV [ESI+EDI], ECX - XOR ESI,ESI - RET - * PUSH EAX - PUSH EDX - PUSH ECX - CALL writemembl - POP ECX - POP EDX - POP EAX - MOVZX ECX, AL - RET - */ - host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); - host_x86_SHR32_IMM(block, REG_ESI, 12); - host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); - if (size != 1) - { - host_x86_TEST32_REG_IMM(block, REG_EDI, size-1); - misaligned_offset = host_x86_JNZ_short(block); - } - host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t)-1); - branch_offset = host_x86_JZ_short(block); - if (size == 1 && !is_float) - host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 2 && !is_float) - host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4 && !is_float) - host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); - else if (size == 4 && is_float) - host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else if (size == 8) - host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); - else - fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); - host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); - host_x86_RET(block); + /*In - ECX = data, ESI = address + Out - ESI = abrt + Corrupts EDI*/ + /*MOV EDI, ESI + SHR ESI, 12 + MOV ESI, [writelookup2+ESI*4] + CMP ESI, -1 + JNZ + + MOV [ESI+EDI], ECX + XOR ESI,ESI + RET + * PUSH EAX + PUSH EDX + PUSH ECX + CALL writemembl + POP ECX + POP EDX + POP EAX + MOVZX ECX, AL + RET + */ + host_x86_MOV32_REG_REG(block, REG_EDI, REG_ESI); + host_x86_SHR32_IMM(block, REG_ESI, 12); + host_x86_MOV32_REG_ABS_INDEX_SHIFT(block, REG_ESI, writelookup2, REG_ESI, 2); + if (size != 1) { + host_x86_TEST32_REG_IMM(block, REG_EDI, size - 1); + misaligned_offset = host_x86_JNZ_short(block); + } + host_x86_CMP32_REG_IMM(block, REG_ESI, (uint32_t) -1); + branch_offset = host_x86_JZ_short(block); + if (size == 1 && !is_float) + host_x86_MOV8_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 2 && !is_float) + host_x86_MOV16_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && !is_float) + host_x86_MOV32_BASE_INDEX_REG(block, REG_ESI, REG_EDI, REG_ECX); + else if (size == 4 && is_float) + host_x86_MOVD_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else if (size == 8) + host_x86_MOVQ_BASE_INDEX_XREG(block, REG_ESI, REG_EDI, REG_XMM_TEMP); + else + fatal("build_store_routine: size=%i is_float=%i\n", size, is_float); + host_x86_XOR32_REG_REG(block, REG_ESI, REG_ESI); + host_x86_RET(block); - *branch_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 1; - if (size != 1) - *misaligned_offset = (uint8_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)misaligned_offset) - 1; - if (size == 4 && is_float) - host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); - host_x86_PUSH(block, REG_EAX); - host_x86_PUSH(block, REG_EDX); - host_x86_PUSH(block, REG_ECX); - if (size == 8) - { - host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); - host_x86_SUB32_REG_IMM(block, REG_ESP, 8); - } - host_x86_PUSH(block, REG_EDI); - if (size == 1) - host_x86_CALL(block, (void *)writemembl); - else if (size == 2) - host_x86_CALL(block, (void *)writememwl); - else if (size == 4) - host_x86_CALL(block, (void *)writememll); - else if (size == 8) - host_x86_CALL(block, (void *)writememql); - host_x86_POP(block, REG_EDI); - if (size == 8) - host_x86_ADD32_REG_IMM(block, REG_ESP, 8); - host_x86_POP(block, REG_ECX); - host_x86_POP(block, REG_EDX); - host_x86_POP(block, REG_EAX); - host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); - host_x86_RET(block); - block_pos = (block_pos + 63) & ~63; + *branch_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 1; + if (size != 1) + *misaligned_offset = (uint8_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) misaligned_offset) - 1; + if (size == 4 && is_float) + host_x86_MOVD_REG_XREG(block, REG_ECX, REG_XMM_TEMP); + host_x86_PUSH(block, REG_EAX); + host_x86_PUSH(block, REG_EDX); + host_x86_PUSH(block, REG_ECX); + if (size == 8) { + host_x86_MOVQ_STACK_OFFSET_XREG(block, -8, REG_XMM_TEMP); + host_x86_SUB32_REG_IMM(block, REG_ESP, 8); + } + host_x86_PUSH(block, REG_EDI); + if (size == 1) + host_x86_CALL(block, (void *) writemembl); + else if (size == 2) + host_x86_CALL(block, (void *) writememwl); + else if (size == 4) + host_x86_CALL(block, (void *) writememll); + else if (size == 8) + host_x86_CALL(block, (void *) writememql); + host_x86_POP(block, REG_EDI); + if (size == 8) + host_x86_ADD32_REG_IMM(block, REG_ESP, 8); + host_x86_POP(block, REG_ECX); + host_x86_POP(block, REG_EDX); + host_x86_POP(block, REG_EAX); + host_x86_MOVZX_REG_ABS_32_8(block, REG_ESI, &cpu_state.abrt); + host_x86_RET(block); + block_pos = (block_pos + 63) & ~63; } -static void build_loadstore_routines(codeblock_t *block) +static void +build_loadstore_routines(codeblock_t *block) { - codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 1, 0); - codegen_mem_load_word = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 2, 0); - codegen_mem_load_long = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 0); - codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 0); - codegen_mem_load_single = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 4, 1); - codegen_mem_load_double = &codeblock[block_current].data[block_pos]; - build_load_routine(block, 8, 1); + codegen_mem_load_byte = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 1, 0); + codegen_mem_load_word = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 2, 0); + codegen_mem_load_long = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 0); + codegen_mem_load_quad = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 0); + codegen_mem_load_single = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 4, 1); + codegen_mem_load_double = &codeblock[block_current].data[block_pos]; + build_load_routine(block, 8, 1); - codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 1, 0); - codegen_mem_store_word = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 2, 0); - codegen_mem_store_long = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 0); - codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 0); - codegen_mem_store_single = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 4, 1); - codegen_mem_store_double = &codeblock[block_current].data[block_pos]; - build_store_routine(block, 8, 1); + codegen_mem_store_byte = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 1, 0); + codegen_mem_store_word = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 2, 0); + codegen_mem_store_long = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 0); + codegen_mem_store_quad = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 0); + codegen_mem_store_single = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 4, 1); + codegen_mem_store_double = &codeblock[block_current].data[block_pos]; + build_store_routine(block, 8, 1); } -void codegen_backend_init(void) +void +codegen_backend_init(void) { - codeblock_t *block; - int c; + codeblock_t *block; + int c; - codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); - codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); + codeblock = malloc(BLOCK_SIZE * sizeof(codeblock_t)); + codeblock_hash = malloc(HASH_SIZE * sizeof(codeblock_t *)); - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(codeblock_t *)); - for (c = 0; c < BLOCK_SIZE; c++) - codeblock[c].pc = BLOCK_PC_INVALID; + for (c = 0; c < BLOCK_SIZE; c++) + codeblock[c].pc = BLOCK_PC_INVALID; - block_current = 0; - block_pos = 0; - block = &codeblock[block_current]; - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block_write_data = block->data; - build_loadstore_routines(block); + block_current = 0; + block_pos = 0; + block = &codeblock[block_current]; + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block_write_data = block->data; + build_loadstore_routines(block); - codegen_gpf_rout = &codeblock[block_current].data[block_pos]; - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); - host_x86_CALL(block, (void *)x86gpf); - codegen_exit_rout = &codeblock[block_current].data[block_pos]; - host_x86_ADD32_REG_IMM(block, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); - block_write_data = NULL; + codegen_gpf_rout = &codeblock[block_current].data[block_pos]; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 0); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, 0); + host_x86_CALL(block, (void *) x86gpf); + codegen_exit_rout = &codeblock[block_current].data[block_pos]; + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); + block_write_data = NULL; - cpu_state.old_fp_control = 0; - asm( - "fstcw %0\n" - "stmxcsr %1\n" - : "=m" (cpu_state.old_fp_control2), - "=m" (cpu_state.old_fp_control) - ); - cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; + cpu_state.old_fp_control = 0; + asm( + "fstcw %0\n" + "stmxcsr %1\n" + : "=m"(cpu_state.old_fp_control2), + "=m"(cpu_state.old_fp_control)); + cpu_state.trunc_fp_control = cpu_state.old_fp_control | 0x6000; } -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /*SSE*/ - cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); - /*x87 - used for double -> i64 conversions*/ - cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); + /*SSE*/ + cpu_state.new_fp_control = (cpu_state.old_fp_control & ~0x6000) | (mode << 13); + /*x87 - used for double -> i64 conversions*/ + cpu_state.new_fp_control2 = (cpu_state.old_fp_control2 & ~0x0c00) | (mode << 10); } -void codegen_backend_prologue(codeblock_t *block) +void +codegen_backend_prologue(codeblock_t *block) { - block_pos = BLOCK_START; /*Entry code*/ - host_x86_PUSH(block, REG_EBX); - host_x86_PUSH(block, REG_EBP); - host_x86_PUSH(block, REG_ESI); - host_x86_PUSH(block, REG_EDI); - host_x86_SUB32_REG_IMM(block, REG_ESP, 64); - host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t)&cpu_state) + 128); - if (block->flags & CODEBLOCK_HAS_FPU) - { - host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); - host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); - } + block_pos = BLOCK_START; /*Entry code*/ + host_x86_PUSH(block, REG_EBX); + host_x86_PUSH(block, REG_EBP); + host_x86_PUSH(block, REG_ESI); + host_x86_PUSH(block, REG_EDI); + host_x86_SUB32_REG_IMM(block, REG_ESP, 64); + host_x86_MOV32_REG_IMM(block, REG_EBP, ((uintptr_t) &cpu_state) + 128); + if (block->flags & CODEBLOCK_HAS_FPU) { + host_x86_MOV32_REG_ABS(block, REG_EAX, &cpu_state.TOP); + host_x86_SUB32_REG_IMM(block, REG_EAX, block->TOP); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, IREG_TOP_diff_stack_offset, REG_EAX); + } } -void codegen_backend_epilogue(codeblock_t *block) +void +codegen_backend_epilogue(codeblock_t *block) { - host_x86_ADD32_REG_IMM(block, REG_ESP, 64); - host_x86_POP(block, REG_EDI); - host_x86_POP(block, REG_ESI); - host_x86_POP(block, REG_EBP); - host_x86_POP(block, REG_EDX); - host_x86_RET(block); + host_x86_ADD32_REG_IMM(block, REG_ESP, 64); + host_x86_POP(block, REG_EDI); + host_x86_POP(block, REG_ESI); + host_x86_POP(block, REG_EBP); + host_x86_POP(block, REG_EDX); + host_x86_RET(block); } #endif diff --git a/src/codegen_new/codegen_backend_x86.h b/src/codegen_new/codegen_backend_x86.h index 582e46430..646289fab 100644 --- a/src/codegen_new/codegen_backend_x86.h +++ b/src/codegen_new/codegen_backend_x86.h @@ -1,14 +1,14 @@ #include "codegen_backend_x86_defs.h" -#define BLOCK_SIZE 0x10000 -#define BLOCK_MASK 0xffff +#define BLOCK_SIZE 0x10000 +#define BLOCK_MASK 0xffff #define BLOCK_START 0 -#define HASH_SIZE 0x20000 -#define HASH_MASK 0x1ffff +#define HASH_SIZE 0x20000 +#define HASH_MASK 0x1ffff -#define HASH(l) ((l) & 0x1ffff) +#define HASH(l) ((l) &0x1ffff) -#define BLOCK_MAX 0x3c0 +#define BLOCK_MAX 0x3c0 #define CODEGEN_BACKEND_HAS_MOV_IMM diff --git a/src/codegen_new/codegen_backend_x86_defs.h b/src/codegen_new/codegen_backend_x86_defs.h index 25964ba3c..a86d6f309 100644 --- a/src/codegen_new/codegen_backend_x86_defs.h +++ b/src/codegen_new/codegen_backend_x86_defs.h @@ -1,28 +1,28 @@ #ifndef _CODEGEN_BACKEND_X86_DEFS_H_ #define _CODEGEN_BACKEND_X86_DEFS_H_ -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 +#define REG_EAX 0 +#define REG_ECX 1 +#define REG_EDX 2 +#define REG_EBX 3 +#define REG_ESP 4 +#define REG_EBP 5 +#define REG_ESI 6 +#define REG_EDI 7 -#define REG_XMM0 0 -#define REG_XMM1 1 -#define REG_XMM2 2 -#define REG_XMM3 3 -#define REG_XMM4 4 -#define REG_XMM5 5 -#define REG_XMM6 6 -#define REG_XMM7 7 +#define REG_XMM0 0 +#define REG_XMM1 1 +#define REG_XMM2 2 +#define REG_XMM3 3 +#define REG_XMM4 4 +#define REG_XMM5 5 +#define REG_XMM6 6 +#define REG_XMM7 7 -#define REG_XMM_TEMP REG_XMM7 -#define REG_XMM_TEMP2 REG_XMM6 +#define REG_XMM_TEMP REG_XMM7 +#define REG_XMM_TEMP2 REG_XMM6 -#define CODEGEN_HOST_REGS 3 +#define CODEGEN_HOST_REGS 3 #define CODEGEN_HOST_FP_REGS 6 extern void *codegen_mem_load_byte; diff --git a/src/codegen_new/codegen_backend_x86_ops.c b/src/codegen_new/codegen_backend_x86_ops.c index 5e89ffbc8..4807caacf 100644 --- a/src/codegen_new/codegen_backend_x86_ops.c +++ b/src/codegen_new/codegen_backend_x86_ops.c @@ -1,1334 +1,1311 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops.h" -#include "codegen_backend_x86_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops.h" +# include "codegen_backend_x86_ops_helpers.h" -#define RM_OP_ADD 0x00 -#define RM_OP_OR 0x08 -#define RM_OP_AND 0x20 -#define RM_OP_SUB 0x28 -#define RM_OP_XOR 0x30 -#define RM_OP_CMP 0x38 +# define RM_OP_ADD 0x00 +# define RM_OP_OR 0x08 +# define RM_OP_AND 0x20 +# define RM_OP_SUB 0x28 +# define RM_OP_XOR 0x30 +# define RM_OP_CMP 0x38 -#define RM_OP_ROL 0x00 -#define RM_OP_ROR 0x08 -#define RM_OP_SHL 0x20 -#define RM_OP_SHR 0x28 -#define RM_OP_SAR 0x38 +# define RM_OP_ROL 0x00 +# define RM_OP_ROR 0x08 +# define RM_OP_SHL 0x20 +# define RM_OP_SHR 0x28 +# define RM_OP_SAR 0x38 -void host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ - } -} -void host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ -} -void host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_addbyte3(block, 0x03, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x03); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_ADD8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x04, imm_data); /*ADD AL, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_ADD | dst_reg, imm_data); /*ADD dst_reg, imm_data*/ + } } - -void host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ - } -} -void host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ -} -void host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ -} -void host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ -} - -void host_x86_CALL(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe8); /*CALL*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} - -void host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} -void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ -} - -void host_x86_INC32_ABS(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ - codegen_addlong(block, (uint32_t)p); -} - -void host_x86_JMP(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} -uint32_t *host_x86_JMP_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_x86_JNZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} -void host_x86_JZ(codeblock_t *block, void *p) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, (uintptr_t)p - (uintptr_t)&block_write_data[block_pos + 4]); -} - -uint8_t *host_x86_JNZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x75, 0); /*JNZ*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JS_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x78, 0); /*JS*/ - return &block_write_data[block_pos-1]; -} -uint8_t *host_x86_JZ_short(codeblock_t *block) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x74, 0); /*JZ*/ - return &block_write_data[block_pos-1]; -} - -uint32_t *host_x86_JNB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JNZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JB_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JBE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JL_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JLE_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JO_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JS_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} -uint32_t *host_x86_JZ_long(codeblock_t *block) -{ - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ - codegen_addlong(block, 0); - return (uint32_t *)&block_write_data[block_pos-4]; -} - -void host_x86_LAHF(codeblock_t *block) -{ - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x9f); /*LAHF*/ -} - -void host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) -{ - if (offset) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ - codegen_addlong(block, offset); - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ - } -} - -void host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ -} -void host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ -} - -void host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ - codegen_addbyte(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addbyte(block, imm_data); - } -} -void host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addword(block, imm_data); - } -} -void host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 10); - codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ - codegen_addlong(block, (uint32_t)p); - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (src_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} - -void host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ -} -void host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +void +host_x86_ADD16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x05); /*ADD AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +void +host_x86_ADD32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_ADD | dst_reg, imm_data & 0xff); /*ADD dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x05); /*ADD EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_ADD | dst_reg); /*ADD dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x00, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) +void +host_x86_ADD32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ - codegen_addbyte(block, 0x05 | (dst_reg << 3)); - codegen_addlong(block, (uint32_t)p); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte2(block, 0x01, 0xc0 | dst_reg | (src_reg << 3)); /*ADD dst_reg, src_reg*/ } -void host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) +void +host_x86_AND8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) { + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x24, imm_data); /*AND AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_AND | dst_reg, imm_data); /*AND dst_reg, imm_data*/ + } +} +void +host_x86_AND16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0x25); /*AND AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_AND32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_AND | dst_reg, imm_data & 0xff); /*AND dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x25); /*AND EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_AND | dst_reg); /*AND dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_AND8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x20, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ +} +void +host_x86_AND16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ +} +void +host_x86_AND32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x21, 0xc0 | dst_reg | (src_reg << 3)); /*AND dst_reg, src_reg_b*/ +} + +void +host_x86_CALL(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe8); /*CALL*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} + +void +host_x86_CMP16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x3d); /*CMP AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } +} +void +host_x86_CMP32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_CMP | dst_reg, imm_data & 0xff); /*CMP dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x3d); /*CMP EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_CMP | dst_reg); /*CMP dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_CMP8_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x38, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP16_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} +void +host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x39, 0xc0 | src_reg_a | (src_reg_b << 3)); /*CMP src_reg_a, src_reg_b*/ +} + +void +host_x86_INC32_ABS(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xff, 0x05); /*INC p*/ + codegen_addlong(block, (uint32_t) p); +} + +void +host_x86_JMP(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} +uint32_t * +host_x86_JMP_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} + +void +host_x86_JNZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} +void +host_x86_JZ(codeblock_t *block, void *p) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, (uintptr_t) p - (uintptr_t) &block_write_data[block_pos + 4]); +} + +uint8_t * +host_x86_JNZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x75, 0); /*JNZ*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JS_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x78, 0); /*JS*/ + return &block_write_data[block_pos - 1]; +} +uint8_t * +host_x86_JZ_short(codeblock_t *block) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x74, 0); /*JZ*/ + return &block_write_data[block_pos - 1]; +} + +uint32_t * +host_x86_JNB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x83); /*JNB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x87); /*JNBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8d); /*JNL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8f); /*JNLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x81); /*JNO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x89); /*JNS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JNZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x85); /*JNZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JB_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x82); /*JB*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JBE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x86); /*JBE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JL_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8c); /*JL*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JLE_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x8e); /*JLE*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JO_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x80); /*JO*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JS_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x88); /*JS*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} +uint32_t * +host_x86_JZ_long(codeblock_t *block) +{ + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x0f, 0x84); /*JZ*/ + codegen_addlong(block, 0); + return (uint32_t *) &block_write_data[block_pos - 4]; +} + +void +host_x86_LAHF(codeblock_t *block) +{ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x9f); /*LAHF*/ +} + +void +host_x86_LEA_REG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint32_t offset) +{ + if (offset) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x8d, 0x80 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [offset+src_reg]*/ + codegen_addlong(block, offset); + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x8d, 0x00 | (dst_reg << 3) | src_reg); /*LEA dst_reg, [src_reg]*/ + } +} + +void +host_x86_LEA_REG_REG(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b]*/ +} +void +host_x86_LEA_REG_REG_SHIFT(codeblock_t *block, int dst_reg, int src_reg_a, int src_reg_b, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8d, 0x04 | (dst_reg << 3), (shift << 6) | (src_reg_b << 3) | src_reg_a); /*LEA dst_reg, [src_reg_a + src_reg_b * (1 << shift)]*/ +} + +void +host_x86_MOV8_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte3(block, 0xc6, 0x45, offset); /*MOVB offset[EBP], imm_data*/ + codegen_addbyte(block, imm_data); + } else { codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ - codegen_addlong(block, (uint32_t)p); + codegen_addbyte2(block, 0xc6, 0x05); /*MOVB p, imm_data*/ + codegen_addlong(block, (uint32_t) p); + codegen_addbyte(block, imm_data); + } +} +void +host_x86_MOV16_ABS_IMM(codeblock_t *block, void *p, uint16_t imm_data) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 9); + codegen_addbyte3(block, 0x66, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) p); + codegen_addword(block, imm_data); + } +} +void +host_x86_MOV32_ABS_IMM(codeblock_t *block, void *p, uint32_t imm_data) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x45, offset); /*MOV offset[EBP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 10); + codegen_addbyte2(block, 0xc7, 0x05); /*MOV p, imm_data*/ + codegen_addlong(block, (uint32_t) p); + codegen_addlong(block, imm_data); + } } -void host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift) +void +host_x86_MOV8_ABS_REG(codeblock_t *block, void *p, int src_reg) { - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ - codegen_addlong(block, addr); - } -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ + codegen_addbyte3(block, 0x88, 0x45 | (src_reg << 3), offset); /*MOVB offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x88); /*MOVB [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } } +void +host_x86_MOV16_ABS_REG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); - } - } - else - fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); -} - -void host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); -} -void host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); - } - } - else - fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); -} - -void host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); - codegen_addlong(block, imm_data); - } - } - else - fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); -} - -void host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ -} -void host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (!imm_data) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (!imm_data) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); -} - -void host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) -{ - if (!offset) - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else if (offset >= -0x80 && offset < 0x80) - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 11); - codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ - codegen_addlong(block, offset); - codegen_addlong(block, imm_data); - } -} - -void host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x89, 0x05 | (src_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_ABS_REG(codeblock_t *block, void *p, int src_reg) { + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ -} -void host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ + codegen_addbyte3(block, 0x89, 0x45 | (src_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x89); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (src_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x66); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV8_ABS_REG_REG_SHIFT_REG(codeblock_t *block, uint32_t addr, int base_reg, int idx_reg, int shift, int src_reg) { + if (addr < 0x80 || addr >= 0xffffff80) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -void host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ -} -void host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ + codegen_addbyte4(block, 0x88, 0x44 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x88, 0x84 | (src_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } -void host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +void +host_x86_MOV8_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x88, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV B[base_reg + idx_reg], src_reg*/ +} +void +host_x86_MOV16_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV W[base_reg + idx_reg], src_reg*/ +} +void +host_x86_MOV32_BASE_INDEX_REG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x04 | (src_reg << 3), base_reg | (idx_reg << 3)); /*MOV L[base_reg + idx_reg], src_reg*/ +} + +void +host_x86_MOV8_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8a, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8a); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } +} +void +host_x86_MOV16_REG_ABS(codeblock_t *block, int dst_reg, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ + codegen_addbyte4(block, 0x66, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x8b, 0x05 | (dst_reg << 3)); /*MOV [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +void +host_x86_MOV32_REG_ABS(codeblock_t *block, int dst_reg, void *p) { + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x45 | (dst_reg << 3), offset); /*MOV offset[EBP], src_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte(block, 0x8b); /*MOV [p], src_reg*/ + codegen_addbyte(block, 0x05 | (dst_reg << 3)); + codegen_addlong(block, (uint32_t) p); + } +} + +void +host_x86_MOV32_REG_ABS_INDEX_SHIFT(codeblock_t *block, int dst_reg, void *p, int idx_reg, int shift) +{ + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), (shift << 6) | (idx_reg << 3) | 0x05); /*MOV dst_reg, [p + idx_reg << shift]*/ + codegen_addlong(block, (uint32_t) p); +} + +void +host_x86_MOV8_REG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int base_reg, int idx_reg, int shift) +{ + if (addr < 0x80 || addr >= 0xffffff80) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ + codegen_addbyte4(block, 0x8a, 0x44 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6), addr & 0xff); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x8a, 0x84 | (dst_reg << 3), base_reg | (idx_reg << 3) | (shift << 6)); /*MOV addr[base_reg + idx_reg << shift], src_reg*/ + codegen_addlong(block, addr); + } } -void host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_REG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOV dst_reg, L[base_reg + idx_reg]*/ } -void host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_MOV16_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) { + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV16_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOV32_REG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x8b, 0x40 | base_reg | (dst_reg << 3), offset); + } + } else + fatal("MOV32_REG_BASE_OFFSET - offset %i\n", offset); +} + +void +host_x86_MOV16_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV16_BASE_OFFSET_REG - offset %i\n", offset); +} +void +host_x86_MOV32_BASE_OFFSET_REG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x89, 0x40 | base_reg | (src_reg << 3), 0x24, offset); + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x89, 0x40 | base_reg | (src_reg << 3), offset); + } + } else + fatal("MOV32_BASE_OFFSET_REG - offset %i\n", offset); +} + +void +host_x86_MOV32_BASE_OFFSET_IMM(codeblock_t *block, int base_reg, int offset, uint32_t imm_data) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x40 | base_reg, 0x24, offset); + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x40 | base_reg, offset); + codegen_addlong(block, imm_data); + } + } else + fatal("MOV32_BASE_OFFSET_IMM - offset %i\n", offset); +} + +void +host_x86_MOV8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xb0 + dst_reg, imm_data); /*MOV reg, imm_data*/ +} +void +host_x86_MOV16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (!imm_data) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOV32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (!imm_data) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (dst_reg << 3)); /*XOR dst_reg, dst_reg*/ + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xb8 + dst_reg); /*MOV reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_MOV8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x88, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +void +host_x86_MOV16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +void +host_x86_MOV32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x89, 0xc0 | dst_reg | (src_reg << 3)); } -void host_x86_POP(codeblock_t *block, int src_reg) +void +host_x86_MOV32_STACK_IMM(codeblock_t *block, int32_t offset, uint32_t imm_data) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ + if (!offset) { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0xc7, 0x04, 0x24); /*MOV [ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xc7, 0x44, 0x24, offset & 0xff); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 11); + codegen_addbyte3(block, 0xc7, 0x84, 0x24); /*MOV offset[ESP], imm_data*/ + codegen_addlong(block, offset); + codegen_addlong(block, imm_data); + } } -void host_x86_PUSH(codeblock_t *block, int src_reg) +void +host_x86_MOVSX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbe, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ +} +void +host_x86_MOVSX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xbf, 0xc0 | (dst_reg << 3) | src_reg); /*MOVSX dst_reg, src_reg*/ } -void host_x86_RET(codeblock_t *block) +void +host_x86_MOVZX_REG_ABS_16_8(codeblock_t *block, int dst_reg, void *p) { - codegen_alloc_bytes(block, 1); - codegen_addbyte(block, 0xc3); /*RET*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_ROL8_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x66); + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +void +host_x86_MOVZX_REG_ABS_32_8(codeblock_t *block, int dst_reg, void *p) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_ROL32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_addbyte4(block, 0x0f, 0xb6, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xb6, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_MOVZX_REG_ABS_32_16(codeblock_t *block, int dst_reg, void *p) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ -} + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); -void host_x86_ROR8_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR16_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_ROR32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte4(block, 0x0f, 0xb7, 0x45 | (dst_reg << 3), offset); /*MOV dest_reg, [EBP+offset]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xb7, 0x05 | (dst_reg << 3)); /*MOVZX dst_reg, [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -#define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) - -void host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +void +host_x86_MOVZX_REG_16_8(codeblock_t *block, int dst_reg, int src_reg) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_8(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb6, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} +void +host_x86_MOVZX_REG_32_16(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0xb7, 0xc0 | (dst_reg << 3) | src_reg); /*MOVZX dst_reg, src_reg*/ +} + +void +host_x86_MOVZX_BASE_INDEX_32_8(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb6, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, B[base_reg + idx_reg]*/ +} +void +host_x86_MOVZX_BASE_INDEX_32_16(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xb7, 0x04 | (dst_reg << 3), base_reg | (idx_reg << 3)); /*MOVZX dst_reg, W[base_reg + idx_reg]*/ +} + +void +host_x86_OR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x08, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ +} +void +host_x86_OR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ +} +void +host_x86_OR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x09, 0xc0 | dst_reg | (src_reg << 3)); /*OR dst_reg, src_reg_b*/ +} + +void +host_x86_OR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} -void host_x86_SAR16_CL(codeblock_t *block, int dst_reg) -{ + codegen_addbyte2(block, 0x0c, imm_data); /*OR AL, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_OR | dst_reg, imm_data); /*OR dst_reg, imm_data*/ + } } -void host_x86_SAR32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ -} - -void host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ -} -void host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_OR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x66, 0x0d); /*OR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_OR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_OR | dst_reg, imm_data & 0xff); /*OR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x0d); /*OR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_OR | dst_reg); /*OR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +void +host_x86_POP(codeblock_t *block, int src_reg) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_SHL16_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ -} -void host_x86_SHL32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x58 | src_reg); /*POP reg*/ } -void host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PUSH(codeblock_t *block, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0x50 | src_reg); /*PUSH reg*/ } -void host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) + +void +host_x86_RET(codeblock_t *block) { + codegen_alloc_bytes(block, 1); + codegen_addbyte(block, 0xc3); /*RET*/ +} + +void +host_x86_ROL8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_ROL32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_ROL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_ROL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_ROR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_ROR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_ROR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_ROR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_ROR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_ROR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +# define MODRM_MOD_REG(rm, reg) (0xc0 | reg | (rm << 3)) + +void +host_x86_SAR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} +void +host_x86_SAR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SAR | dst_reg); /*SAR dst_reg, CL*/ +} + +void +host_x86_SAR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} +void +host_x86_SAR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SAR | dst_reg, shift); /*SAR dst_reg, shift*/ +} + +void +host_x86_SHL8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} +void +host_x86_SHL32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHL | dst_reg); /*SHL dst_reg, CL*/ +} + +void +host_x86_SHL8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} +void +host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ +} + +void +host_x86_SHR8_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR16_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} +void +host_x86_SHR32_CL(codeblock_t *block, int dst_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ +} + +void +host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} +void +host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ +} + +void +host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ + } else { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ + } +} +void +host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +{ + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} -void host_x86_SHL32_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHL | dst_reg, shift); /*SHL dst_reg, shift*/ -} - -void host_x86_SHR8_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd2, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR16_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} -void host_x86_SHR32_CL(codeblock_t *block, int dst_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xd3, 0xc0 | RM_OP_SHR | dst_reg); /*SHR dst_reg, CL*/ -} - -void host_x86_SHR8_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc0, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ -} -void host_x86_SHR16_IMM(codeblock_t *block, int dst_reg, int shift) -{ + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } -void host_x86_SHR32_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xc1, 0xc0 | RM_OP_SHR | dst_reg, shift); /*SHR dst_reg, shift*/ + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } -void host_x86_SUB8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +void +host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x2c, imm_data); /*SUB AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_SUB | dst_reg, imm_data); /*SUB dst_reg, imm_data*/ - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) +void +host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x2d); /*SUB AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +void +host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) { - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_SUB | dst_reg, imm_data & 0xff); /*SUB dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x2d); /*SUB EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_SUB | dst_reg); /*SUB dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ } -void host_x86_SUB8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ +} +void +host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) +{ + if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } +} + +void +host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ +} +void +host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ +} +void +host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ +} + +void +host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) +{ + if (dst_reg == REG_EAX) { codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x28, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ -} -void host_x86_SUB16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ + codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ + } else { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ + } } -void host_x86_SUB32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x29, 0xc0 | dst_reg | (src_reg << 3)); /*SUB dst_reg, src_reg*/ + if (is_imm8(imm_data)) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 4); + codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ + codegen_addword(block, imm_data); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addword(block, imm_data); + } } - -void host_x86_TEST8_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x84, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST16_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) +void +host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) { + if (is_imm8(imm_data)) { codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG(codeblock_t *block, int src_host_reg, int dst_host_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x85, MODRM_MOD_REG(dst_host_reg, src_host_reg)); /*TEST dst_host_reg, src_host_reg*/ -} -void host_x86_TEST32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0xa9); /*TEST EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xf7, 0xc0 | dst_reg); /*TEST dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } -} - -void host_x86_XOR8_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x30, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR16_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x66, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ -} -void host_x86_XOR32_REG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x31, 0xc0 | dst_reg | (src_reg << 3)); /*XOR dst_reg, src_reg*/ -} - -void host_x86_XOR8_REG_IMM(codeblock_t *block, int dst_reg, uint8_t imm_data) -{ - if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0x34, imm_data); /*XOR AL, imm_data*/ - } - else - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x80, 0xc0 | RM_OP_XOR | dst_reg, imm_data); /*XOR dst_reg, imm_data*/ - } -} -void host_x86_XOR16_REG_IMM(codeblock_t *block, int dst_reg, uint16_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte2(block, 0x66, 0x35); /*XOR AX, imm_data*/ - codegen_addword(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte3(block, 0x66, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addword(block, imm_data); - } -} -void host_x86_XOR32_REG_IMM(codeblock_t *block, int dst_reg, uint32_t imm_data) -{ - if (is_imm8(imm_data)) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ - } - else if (dst_reg == REG_EAX) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ - codegen_addlong(block, imm_data); - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ - codegen_addlong(block, imm_data); - } + codegen_addbyte3(block, 0x83, 0xc0 | RM_OP_XOR | dst_reg, imm_data & 0xff); /*XOR dst_reg, imm_data*/ + } else if (dst_reg == REG_EAX) { + codegen_alloc_bytes(block, 5); + codegen_addbyte(block, 0x35); /*XOR EAX, imm_data*/ + codegen_addlong(block, imm_data); + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0x81, 0xc0 | RM_OP_XOR | dst_reg); /*XOR dst_reg, imm_data*/ + codegen_addlong(block, imm_data); + } } #endif diff --git a/src/codegen_new/codegen_backend_x86_ops.h b/src/codegen_new/codegen_backend_x86_ops.h index 53b6e0e73..0890286ef 100644 --- a/src/codegen_new/codegen_backend_x86_ops.h +++ b/src/codegen_new/codegen_backend_x86_ops.h @@ -27,7 +27,7 @@ void host_x86_CMP32_REG_REG(codeblock_t *block, int src_reg_a, int src_reg_b); void host_x86_INC32_ABS(codeblock_t *block, void *p); -void host_x86_JMP(codeblock_t *block, void *p); +void host_x86_JMP(codeblock_t *block, void *p); uint32_t *host_x86_JMP_short(codeblock_t *block); uint32_t *host_x86_JMP_long(codeblock_t *block); diff --git a/src/codegen_new/codegen_backend_x86_ops_fpu.c b/src/codegen_new/codegen_backend_x86_ops_fpu.c index cb8f36ac6..13f90743a 100644 --- a/src/codegen_new/codegen_backend_x86_ops_fpu.c +++ b/src/codegen_new/codegen_backend_x86_ops_fpu.c @@ -1,84 +1,74 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops_fpu.h" -#include "codegen_backend_x86_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops_fpu.h" +# include "codegen_backend_x86_ops_helpers.h" -void host_x87_FILDq_BASE(codeblock_t *block, int base_reg) +void +host_x87_FILDq_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x2c, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x28 | base_reg); /*FILDq [base_reg]*/ + } } -void host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) +void +host_x87_FISTPq_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdf, 0x3c, 0x24); /*FISTPq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdf, 0x38 | base_reg); /*FISTPq [base_reg]*/ + } } -void host_x87_FLDCW(codeblock_t *block, void *p) +void +host_x87_FLDCW(codeblock_t *block, void *p) { - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ - } - else - { - codegen_alloc_bytes(block, 6); - codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ - codegen_addlong(block, (uint32_t)p); - } + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xd9, 0x68 | REG_EBP, offset); /*FLDCW offset[EBP]*/ + } else { + codegen_alloc_bytes(block, 6); + codegen_addbyte2(block, 0xd9, 0x2d); /*FLDCW [p]*/ + codegen_addlong(block, (uint32_t) p); + } } -void host_x87_FLDd_BASE(codeblock_t *block, int base_reg) +void +host_x87_FLDd_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x04, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x08 | base_reg); /*FILDq [base_reg]*/ + } } -void host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) +void +host_x87_FSTPd_BASE(codeblock_t *block, int base_reg) { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ - } - else - { - codegen_alloc_bytes(block, 2); - codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ - } + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0xdd, 0x1c, 0x24); /*FILDq [ESP]*/ + } else { + codegen_alloc_bytes(block, 2); + codegen_addbyte2(block, 0xdd, 0x18 | base_reg); /*FILDq [base_reg]*/ + } } #endif diff --git a/src/codegen_new/codegen_backend_x86_ops_helpers.h b/src/codegen_new/codegen_backend_x86_ops_helpers.h index 3fca4f4d2..0a6469a89 100644 --- a/src/codegen_new/codegen_backend_x86_ops_helpers.h +++ b/src/codegen_new/codegen_backend_x86_ops_helpers.h @@ -1,84 +1,94 @@ #define JMP_LEN_BYTES 5 -static inline void codegen_addbyte(codeblock_t *block, uint8_t val) +static inline void +codegen_addbyte(codeblock_t *block, uint8_t val) { - if (block_pos >= BLOCK_MAX) - fatal("codegen_addbyte over! %i\n", block_pos); - block_write_data[block_pos++] = val; + if (block_pos >= BLOCK_MAX) + fatal("codegen_addbyte over! %i\n", block_pos); + block_write_data[block_pos++] = val; } -static inline void codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) +static inline void +codegen_addbyte2(codeblock_t *block, uint8_t vala, uint8_t valb) { - if (block_pos > (BLOCK_MAX-2)) - fatal("codegen_addbyte2 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; + if (block_pos > (BLOCK_MAX - 2)) + fatal("codegen_addbyte2 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; } -static inline void codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) +static inline void +codegen_addbyte3(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc) { - if (block_pos > (BLOCK_MAX-3)) - fatal("codegen_addbyte3 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; + if (block_pos > (BLOCK_MAX - 3)) + fatal("codegen_addbyte3 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; } -static inline void codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) +static inline void +codegen_addbyte4(codeblock_t *block, uint8_t vala, uint8_t valb, uint8_t valc, uint8_t vald) { - if (block_pos > (BLOCK_MAX-4)) - fatal("codegen_addbyte4 over! %i\n", block_pos); - block_write_data[block_pos++] = vala; - block_write_data[block_pos++] = valb; - block_write_data[block_pos++] = valc; - block_write_data[block_pos++] = vald; + if (block_pos > (BLOCK_MAX - 4)) + fatal("codegen_addbyte4 over! %i\n", block_pos); + block_write_data[block_pos++] = vala; + block_write_data[block_pos++] = valb; + block_write_data[block_pos++] = valc; + block_write_data[block_pos++] = vald; } -static inline void codegen_addword(codeblock_t *block, uint16_t val) +static inline void +codegen_addword(codeblock_t *block, uint16_t val) { - if (block_pos > (BLOCK_MAX-2)) - fatal("codegen_addword over! %i\n", block_pos); - *(uint16_t *)&block_write_data[block_pos] = val; - block_pos += 2; + if (block_pos > (BLOCK_MAX - 2)) + fatal("codegen_addword over! %i\n", block_pos); + *(uint16_t *) &block_write_data[block_pos] = val; + block_pos += 2; } -static inline void codegen_addlong(codeblock_t *block, uint32_t val) +static inline void +codegen_addlong(codeblock_t *block, uint32_t val) { - if (block_pos > (BLOCK_MAX-4)) - fatal("codegen_addlong over! %i\n", block_pos); - *(uint32_t *)&block_write_data[block_pos] = val; - block_pos += 4; + if (block_pos > (BLOCK_MAX - 4)) + fatal("codegen_addlong over! %i\n", block_pos); + *(uint32_t *) &block_write_data[block_pos] = val; + block_pos += 4; } -static inline void codegen_addquad(codeblock_t *block, uint64_t val) +static inline void +codegen_addquad(codeblock_t *block, uint64_t val) { - if (block_pos > (BLOCK_MAX-8)) - fatal("codegen_addquad over! %i\n", block_pos); - *(uint64_t *)&block_write_data[block_pos] = val; - block_pos += 8; + if (block_pos > (BLOCK_MAX - 8)) + fatal("codegen_addquad over! %i\n", block_pos); + *(uint64_t *) &block_write_data[block_pos] = val; + block_pos += 8; } -static void codegen_allocate_new_block(codeblock_t *block) +static void +codegen_allocate_new_block(codeblock_t *block) { - /*Current block is full. Allocate a new block*/ - struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); - uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); + /*Current block is full. Allocate a new block*/ + struct mem_block_t *new_block = codegen_allocator_allocate(block->head_mem_block, get_block_nr(block)); + uint8_t *new_ptr = codeblock_allocator_get_ptr(new_block); - /*Add a jump instruction to the new block*/ - codegen_addbyte(block, 0xe9); /*JMP*/ - codegen_addlong(block, (uintptr_t)new_ptr - (uintptr_t)&block_write_data[block_pos + 4]); + /*Add a jump instruction to the new block*/ + codegen_addbyte(block, 0xe9); /*JMP*/ + codegen_addlong(block, (uintptr_t) new_ptr - (uintptr_t) &block_write_data[block_pos + 4]); - /*Set write address to start of new block*/ - block_pos = 0; - block_write_data = new_ptr; + /*Set write address to start of new block*/ + block_pos = 0; + block_write_data = new_ptr; } -static inline void codegen_alloc_bytes(codeblock_t *block, int size) +static inline void +codegen_alloc_bytes(codeblock_t *block, int size) { - if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) - codegen_allocate_new_block(block); + if (block_pos > ((BLOCK_MAX - size) - JMP_LEN_BYTES)) + codegen_allocate_new_block(block); } -static inline int is_imm8(uint32_t imm_data) +static inline int +is_imm8(uint32_t imm_data) { - if (imm_data <= 0x7f || imm_data >= 0xffffff80) - return 1; - return 0; + if (imm_data <= 0x7f || imm_data >= 0xffffff80) + return 1; + return 0; } diff --git a/src/codegen_new/codegen_backend_x86_ops_sse.c b/src/codegen_new/codegen_backend_x86_ops_sse.c index 0ab461e74..a1e04db30 100644 --- a/src/codegen_new/codegen_backend_x86_ops_sse.c +++ b/src/codegen_new/codegen_backend_x86_ops_sse.c @@ -1,578 +1,629 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops_sse.h" -#include "codegen_backend_x86_ops_helpers.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops_sse.h" +# include "codegen_backend_x86_ops_helpers.h" -void host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); /*ADDPS dst_reg, src_reg*/ } -void host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_ADDSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x58, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) +void +host_x86_CMPPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg, int type) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xc2, 0xc0 | src_reg | (dst_reg << 3), type); /*CMPPS dst_reg, src_reg, type*/ } -void host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) +void +host_x86_COMISD_XREG_XREG(codeblock_t *block, int src_reg_a, int src_reg_b) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x2e, 0xc0 | src_reg_b | (src_reg_a << 3)); } -void host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTDQ2PS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTDQ2PS dst_reg, src_reg*/ } -void host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTPS2DQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x5b, 0xc0 | src_reg | (dst_reg << 3)); /*CVTPS2DQ dst_reg, src_reg*/ } -void host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSD2SI_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2d, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SI dst_reg, src_reg*/ } -void host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSD2SS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSD2SS dst_reg, src_reg*/ } -void host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSI2SD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } -void host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSI2SS_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x2a, 0xc0 | src_reg | (dst_reg << 3)); /*CVTSI2SD dst_reg, src_reg*/ } -void host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_CVTSS2SD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +void +host_x86_CVTSS2SD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} + +void +host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ +} +void +host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ +} + +void +host_x86_LDMXCSR(codeblock_t *block, void *p) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ + } else { + codegen_alloc_bytes(block, 7); + codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ + codegen_addlong(block, (uint32_t) p); + } +} + +void +host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ +} + +void +host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); +} +void +host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) +{ + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5a, 0x04 | (dst_reg << 3)); /*CVTSS2SD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } } - -void host_x86_DIVSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSD dst_reg, src_reg*/ -} -void host_x86_DIVSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x5e, 0xc0 | src_reg | (dst_reg << 3)); /*DIVSS dst_reg, src_reg*/ -} - -void host_x86_LDMXCSR(codeblock_t *block, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x0f, 0xae, 0x50 | REG_EBP, offset); /*LDMXCSR offset[EBP]*/ - } - else - { - codegen_alloc_bytes(block, 7); - codegen_addbyte3(block, 0x0f, 0xae, 0x15); /*LDMXCSR [p]*/ - codegen_addlong(block, (uint32_t)p); - } -} - -void host_x86_MAXSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXSD dst_reg, src_reg*/ -} - -void host_x86_MOVD_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0x04 | (src_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_REG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x7e, 0xc0 | dst_reg | (src_reg << 3)); -} -void host_x86_MOVD_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0x04 | (dst_reg << 3)); /*MOVD XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVD_XREG_REG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x6e, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_MOVQ_ABS_XREG(codeblock_t *block, void *p, int src_reg) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x45 | (src_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x05 | (src_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ - codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); -} -void host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) -{ - if (!offset) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ - codegen_addbyte(block, 0x24); - } - else if (offset >= -0x80 && offset < 0x80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte2(block, 0x24, offset & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ - codegen_addbyte(block, 0x24); - codegen_addlong(block, offset); - } - -} - -void host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) -{ - int offset = (uintptr_t)p - (((uintptr_t)&cpu_state) + 128); - - if (offset >= -128 && offset < 127) - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ - codegen_addbyte(block, offset); - } - else - { - codegen_alloc_bytes(block, 8); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ - codegen_addlong(block, (uint32_t)p); - } -} -void host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) -{ - if (addr < 0x80 || addr >= 0xffffff80) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); - } - else - { - codegen_alloc_bytes(block, 9); - codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ - codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); - codegen_addlong(block, addr); - } -} -void host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ - codegen_addbyte(block, base_reg | (idx_reg << 3)); -} -void host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) -{ - if (offset >= -128 && offset < 127) - { - if (base_reg == REG_ESP) - { - codegen_alloc_bytes(block, 6); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ - codegen_addbyte2(block, 0x24, offset); - } - else - { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ - codegen_addbyte(block, offset); - } - } - else - fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); -} -void host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ -} - -void host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ -} -void host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ -} - -void host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ -} -void host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); -} - -void host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(codeblock_t *block, uint32_t addr, int src_reg_a, int src_reg_b, int shift, int src_reg) { + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte3(block, 0x44 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte3(block, 0x66, 0x0f, 0xd6); /*MOVQ addr[src_reg_a + src_reg_b << shift], XMMx*/ + codegen_addbyte2(block, 0x84 | (src_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } } -void host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MOVQ_BASE_INDEX_XREG(codeblock_t *block, int base_reg, int idx_reg, int src_reg) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVQ_BASE_OFFSET_XREG(codeblock_t *block, int base_reg, int offset, int src_reg) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ [ESP + offset], XMMx*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x40 | base_reg | (src_reg << 3)); /*MOVQ [base_reg + offset], XMMx*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_BASE_OFFSET_XREG - offset %i\n", offset); +} +void +host_x86_MOVQ_STACK_OFFSET_XREG(codeblock_t *block, int offset, int src_reg) +{ + if (!offset) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x04 | (src_reg << 3)); /*MOVQ [ESP], src_reg*/ + codegen_addbyte(block, 0x24); + } else if (offset >= -0x80 && offset < 0x80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x44 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte2(block, 0x24, offset & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte4(block, 0x66, 0x0f, 0xd6, 0x84 | (src_reg << 3)); /*MOVQ offset[ESP], src_reg*/ + codegen_addbyte(block, 0x24); + codegen_addlong(block, offset); + } } -void host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) + +void +host_x86_MOVQ_XREG_ABS(codeblock_t *block, int dst_reg, void *p) { + int offset = (uintptr_t) p - (((uintptr_t) &cpu_state) + 128); + + if (offset >= -128 && offset < 127) { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x45 | (dst_reg << 3)); /*MOVQ offset[EBP], src_reg*/ + codegen_addbyte(block, offset); + } else { + codegen_alloc_bytes(block, 8); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x05 | (dst_reg << 3)); /*MOVQ [p], src_reg*/ + codegen_addlong(block, (uint32_t) p); + } +} +void +host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(codeblock_t *block, int dst_reg, uint32_t addr, int src_reg_a, int src_reg_b, int shift) +{ + if (addr < 0x80 || addr >= 0xffffff80) { + codegen_alloc_bytes(block, 6); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte3(block, 0x44 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6), addr & 0xff); + } else { codegen_alloc_bytes(block, 9); - codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ - codegen_addbyte(block, 0x88); + codegen_addbyte3(block, 0xf3, 0x0f, 0x7e); /*MOVQ XMMx, addr[src_reg_a + src_reg_b << shift]*/ + codegen_addbyte2(block, 0x84 | (dst_reg << 3), src_reg_a | (src_reg_b << 3) | (shift << 6)); + codegen_addlong(block, addr); + } +} +void +host_x86_MOVQ_XREG_BASE_INDEX(codeblock_t *block, int dst_reg, int base_reg, int idx_reg) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x04 | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + idx_reg]*/ + codegen_addbyte(block, base_reg | (idx_reg << 3)); +} +void +host_x86_MOVQ_XREG_BASE_OFFSET(codeblock_t *block, int dst_reg, int base_reg, int offset) +{ + if (offset >= -128 && offset < 127) { + if (base_reg == REG_ESP) { + codegen_alloc_bytes(block, 6); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x44 | (dst_reg << 3)); /*MOVQ XMMx, [ESP + offset]*/ + codegen_addbyte2(block, 0x24, offset); + } else { + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0x40 | base_reg | (dst_reg << 3)); /*MOVQ XMMx, [base_reg + offset]*/ + codegen_addbyte(block, offset); + } + } else + fatal("MOVQ_REG_BASE_OFFSET - offset %i\n", offset); +} +void +host_x86_MOVQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x7e, 0xc0 | src_reg | (dst_reg << 3)); /*MOVQ dst_reg, src_reg*/ } -void host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MAXPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5f, 0xc0 | src_reg | (dst_reg << 3)); /*MAXPS dst_reg, src_reg*/ } -void host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MINPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ -} -void host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ -} -void host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ -} -void host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ -} -void host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5d, 0xc0 | src_reg | (dst_reg << 3)); /*MINPS dst_reg, src_reg*/ } -void host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MULPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); /*MULPS dst_reg, src_reg*/ } -void host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_MULSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ -} -void host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ -} -void host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x59, 0xc0 | src_reg | (dst_reg << 3)); } -void host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PACKSSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x63, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } -void host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PACKSSDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x6b, 0xc0 | src_reg | (dst_reg << 3)); /*PACKSSDW dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } -void host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PACKUSWB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ -} -void host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ -} -void host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ -} -void host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 9); + codegen_addbyte4(block, 0x66, 0x0f, 0x67, 0xc0 | src_reg | (dst_reg << 3)); /*PACKUSWB dst_reg, src_reg*/ + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | dst_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0x88 (move bits 64-95 to 32-63)*/ + codegen_addbyte(block, 0x88); } -void host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PADDB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } -void host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PADDW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ } -void host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PADDD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfe, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PADDSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xec, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSB dst_reg, src_reg*/ +} +void +host_x86_PADDSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xed, 0xc0 | src_reg | (dst_reg << 3)); /*PADDSW dst_reg, src_reg*/ +} +void +host_x86_PADDUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdc, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSB dst_reg, src_reg*/ +} +void +host_x86_PADDUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdd, 0xc0 | src_reg | (dst_reg << 3)); /*PADDUSW dst_reg, src_reg*/ } -void host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) +void +host_x86_PAND_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ - codegen_addbyte(block, shuffle); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdb, 0xc0 | src_reg | (dst_reg << 3)); /*PAND dst_reg, src_reg*/ +} +void +host_x86_PANDN_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xdf, 0xc0 | src_reg | (dst_reg << 3)); /*PANDN dst_reg, src_reg*/ +} +void +host_x86_POR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xeb, 0xc0 | src_reg | (dst_reg << 3)); /*POR dst_reg, src_reg*/ +} +void +host_x86_PXOR_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xef, 0xc0 | src_reg | (dst_reg << 3)); /*PXOR dst_reg, src_reg*/ } -void host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPEQB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x74, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQB dst_reg, src_reg*/ } -void host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPEQW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x75, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQW dst_reg, src_reg*/ } -void host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPEQD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x76, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPEQD dst_reg, src_reg*/ } -void host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPGTB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x64, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTB dst_reg, src_reg*/ } -void host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPGTW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x65, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTW dst_reg, src_reg*/ } -void host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +void +host_x86_PCMPGTD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); -} -void host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) -{ - codegen_alloc_bytes(block, 5); - codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ - codegen_addbyte(block, shift); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x66, 0xc0 | src_reg | (dst_reg << 3)); /*PCMPGTD dst_reg, src_reg*/ } -void host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PMADDWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } -void host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PMULHW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } -void host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PMULLW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ -} -void host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ -} -void host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ -} -void host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ -} -void host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd5, 0xc0 | src_reg | (dst_reg << 3)); /*PMULLW dst_reg, src_reg*/ } -void host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSHUFD_XREG_XREG_IMM(codeblock_t *block, int dst_reg, int src_reg, uint8_t shuffle) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ -} -void host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ -} -void host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) -{ - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x70, 0xc0 | src_reg | (dst_reg << 3)); /*PSHUFD dst_reg, dst_reg, 0xee (move top 64-bits to low 64-bits)*/ + codegen_addbyte(block, shuffle); } -void host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSLLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x30 | dst_reg); /*PSLLW dst_reg, imm*/ + codegen_addbyte(block, shift); } -void host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSLLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSLLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x30 | dst_reg); /*PSLLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x20 | dst_reg); /*PSRAW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRAQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x20 | dst_reg); /*PSRAD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLW_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x71, 0xc0 | 0x10 | dst_reg); /*PSRLW dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLD_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x72, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); +} +void +host_x86_PSRLQ_XREG_IMM(codeblock_t *block, int dst_reg, int shift) +{ + codegen_alloc_bytes(block, 5); + codegen_addbyte4(block, 0x66, 0x0f, 0x73, 0xc0 | 0x10 | dst_reg); /*PSRLD dst_reg, imm*/ + codegen_addbyte(block, shift); } -void host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSUBB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf8, 0xc0 | src_reg | (dst_reg << 3)); /*PADDB dst_reg, src_reg*/ } -void host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PSUBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 4); - codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xf9, 0xc0 | src_reg | (dst_reg << 3)); /*PADDW dst_reg, src_reg*/ +} +void +host_x86_PSUBD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xfa, 0xc0 | src_reg | (dst_reg << 3)); /*PADDD dst_reg, src_reg*/ +} +void +host_x86_PSUBSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSB dst_reg, src_reg*/ +} +void +host_x86_PSUBSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xe9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBSW dst_reg, src_reg*/ +} +void +host_x86_PSUBUSB_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd8, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSB dst_reg, src_reg*/ +} +void +host_x86_PSUBUSW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0xd9, 0xc0 | src_reg | (dst_reg << 3)); /*PSUBUSW dst_reg, src_reg*/ } -void host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +void +host_x86_PUNPCKLBW_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) { - codegen_alloc_bytes(block, 3); - codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x60, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLBW dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLWD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x61, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLWD dst_reg, src_reg*/ +} +void +host_x86_PUNPCKLDQ_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0x66, 0x0f, 0x62, 0xc0 | src_reg | (dst_reg << 3)); /*PUNPCKLDQ dst_reg, src_reg*/ +} + +void +host_x86_SQRTSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSD dst_reg, src_reg*/ +} +void +host_x86_SQRTSS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf3, 0x0f, 0x51, 0xc0 | src_reg | (dst_reg << 3)); /*SQRTSS dst_reg, src_reg*/ +} + +void +host_x86_SUBPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); /*SUBPS dst_reg, src_reg*/ +} +void +host_x86_SUBSD_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 4); + codegen_addbyte4(block, 0xf2, 0x0f, 0x5c, 0xc0 | src_reg | (dst_reg << 3)); +} + +void +host_x86_UNPCKLPS_XREG_XREG(codeblock_t *block, int dst_reg, int src_reg) +{ + codegen_alloc_bytes(block, 3); + codegen_addbyte3(block, 0x0f, 0x14, 0xc0 | src_reg | (dst_reg << 3)); } #endif diff --git a/src/codegen_new/codegen_backend_x86_uops.c b/src/codegen_new/codegen_backend_x86_uops.c index 3f7e2dd9a..83844b3cd 100644 --- a/src/codegen_new/codegen_backend_x86_uops.c +++ b/src/codegen_new/codegen_backend_x86_uops.c @@ -1,3164 +1,3286 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -#include -#include <86box/86box.h> -#include "cpu.h" -#include <86box/mem.h> +# include +# include <86box/86box.h> +# include "cpu.h" +# include <86box/mem.h> -#include "x86.h" -#include "x86_ops.h" -#include "386_common.h" -#include "codegen.h" -#include "codegen_allocator.h" -#include "codegen_backend.h" -#include "codegen_backend_x86_defs.h" -#include "codegen_backend_x86_ops.h" -#include "codegen_backend_x86_ops_fpu.h" -#include "codegen_backend_x86_ops_sse.h" -#include "codegen_ir_defs.h" +# include "x86.h" +# include "x86_ops.h" +# include "386_common.h" +# include "codegen.h" +# include "codegen_allocator.h" +# include "codegen_backend.h" +# include "codegen_backend_x86_defs.h" +# include "codegen_backend_x86_ops.h" +# include "codegen_backend_x86_ops_fpu.h" +# include "codegen_backend_x86_ops_sse.h" +# include "codegen_ir_defs.h" -#define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) -#define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) -#define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) -#define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4) +# define HOST_REG_IS_L(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_L) +# define HOST_REG_IS_W(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_W) +# define HOST_REG_IS_B(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_B && IREG_GET_REG(reg) < 4) +# define HOST_REG_IS_BH(reg) (IREG_GET_SIZE(reg) == IREG_SIZE_BH && IREG_GET_REG(reg) < 4) -#define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) & 3) | 4) : (IREG_GET_REG(reg) & 7)) +# define HOST_REG_GET(reg) ((IREG_GET_SIZE(reg) == IREG_SIZE_BH) ? (IREG_GET_REG((reg) &3) | 4) : (IREG_GET_REG(reg) & 7)) -#define REG_IS_L(size) (size == IREG_SIZE_L) -#define REG_IS_W(size) (size == IREG_SIZE_W) -#define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) -#define REG_IS_BH(size) (size == IREG_SIZE_BH) -#define REG_IS_D(size) (size == IREG_SIZE_D) -#define REG_IS_Q(size) (size == IREG_SIZE_Q) +# define REG_IS_L(size) (size == IREG_SIZE_L) +# define REG_IS_W(size) (size == IREG_SIZE_W) +# define REG_IS_B(size) (size == IREG_SIZE_B || size == IREG_SIZE_BH) +# define REG_IS_BH(size) (size == IREG_SIZE_BH) +# define REG_IS_D(size) (size == IREG_SIZE_D) +# define REG_IS_Q(size) (size == IREG_SIZE_Q) -static int codegen_ADD(codeblock_t *block, uop_t *uop) +static int +codegen_ADD(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); - else - host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_REG(block, dest_reg, src_reg_a, src_reg_b); else - fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + host_x86_ADD32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_ADD8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_ADD_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); - else - host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_LEA_REG_IMM(block, dest_reg, src_reg, uop->imm_data); else - fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + host_x86_ADD32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ADD16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ADD8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ADD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) +static int +codegen_ADD_LSHIFT(codeblock_t *block, uop_t *uop) { - if (!uop->imm_data) - { - if (uop->dest_reg_a_real == uop->src_reg_a_real) - host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); - else - host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); - } - else if (uop->imm_data < 4) - host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); -#ifdef RECOMPILER_DEBUG + if (!uop->imm_data) { + if (uop->dest_reg_a_real == uop->src_reg_a_real) + host_x86_ADD32_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_b_real); else - fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); -#endif - return 0; + host_x86_LEA_REG_REG(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); + } else if (uop->imm_data < 4) + host_x86_LEA_REG_REG_SHIFT(block, uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real, uop->imm_data); +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_ADD_LSHIFT - shift out of range %i\n", uop->imm_data); +# endif + return 0; } -static int codegen_AND(codeblock_t *block, uop_t *uop) +static int +codegen_AND(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PAND_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_AND8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_AND_IMM(codeblock_t *block, uop_t *uop) +static int +codegen_AND_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_AND32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_AND16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_AND8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("AND_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; } -static int codegen_ANDN(codeblock_t *block, uop_t *uop) +static int +codegen_ANDN(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), /*src_reg_a = HOST_REG_GET(uop->src_reg_a_real), */ src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PANDN_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ANDN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); + host_x86_CALL(block, uop->p); - return 0; + return 0; } -static int codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_FUNC_RESULT(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_L(dest_size)) - fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); -#endif - host_x86_CALL(block, uop->p); - host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); + if (!REG_IS_L(dest_size)) + fatal("CALL_FUNC_RESULT %02x\n", uop->dest_reg_a_real); +# endif + host_x86_CALL(block, uop->p); + host_x86_MOV32_REG_REG(block, dest_reg, REG_EAX); - return 0; + return 0; } -static int codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) +static int +codegen_CALL_INSTRUCTION_FUNC(codeblock_t *block, uop_t *uop) { - host_x86_CALL(block, uop->p); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); -// host_x86_CALL(block, codegen_debug); + host_x86_CALL(block, uop->p); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + // host_x86_CALL(block, codegen_debug); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); -#endif - host_x86_JZ(block, uop->p); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ %02x\n", uop->src_reg_a_real); +# endif + host_x86_JZ(block, uop->p); - return 0; + return 0; } -static int codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_IMM_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_L(src_size)) - { - host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); - } - else if (REG_IS_W(src_size)) - { - host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size)) { + host_x86_CMP32_REG_IMM(block, src_reg, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_CMP16_REG_IMM(block, src_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_IMM_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JB_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JB_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - uint32_t *jump_p; + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *jump_p; - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); -#endif - jump_p = host_x86_JNBE_long(block); - *jump_p = (uintptr_t)uop->p - ((uintptr_t)jump_p + 4); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE %02x\n", uop->src_reg_a_real); +# endif + jump_p = host_x86_JNBE_long(block); + *jump_p = (uintptr_t) uop->p - ((uintptr_t) jump_p + 4); - return 0; + return 0; } -static int codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNB_long(block); - return 0; + return 0; } -static int codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNL_long(block); - return 0; + return 0; } -static int codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNO_long(block); - return 0; + return 0; } -static int codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JNZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JNZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNZ_long(block); - return 0; + return 0; } -static int codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JB_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JB_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JB_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JB_long(block); - return 0; + return 0; } -static int codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JBE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JBE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JBE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JBE_long(block); - return 0; + return 0; } -static int codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JL_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JL_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JL_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JL_long(block); - return 0; + return 0; } -static int codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JLE_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JLE_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JLE_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JLE_long(block); - return 0; + return 0; } -static int codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JO_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JO_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JO_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JO_long(block); - return 0; + return 0; } -static int codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) +static int +codegen_CMP_JZ_DEST(codeblock_t *block, uop_t *uop) { - int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + int src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); - } - else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JZ_long(block); + if (REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + host_x86_CMP32_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + host_x86_CMP16_REG_REG(block, src_reg_a, src_reg_b); + } else if (REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + host_x86_CMP8_REG_REG(block, src_reg_a, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("CMP_JZ_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JZ_long(block); - return 0; + return 0; } -static int codegen_FABS(codeblock_t *block, uop_t *uop) +static int +codegen_FABS(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); - host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && dest_reg == src_reg_a) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, dest_reg); + host_x86_MAXSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_FCHS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); + host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_FSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) { + host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_FTST(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) { + host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FABS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FCHS(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_PXOR_XREG_XREG(block, dest_reg, dest_reg); - host_x86_SUBSD_XREG_XREG(block, dest_reg, REG_XMM_TEMP); +static int +codegen_FADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_FCOM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + if (dest_reg != REG_EAX) + host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); + host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); + host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); + host_x86_LAHF(block); + host_x86_AND16_REG_IMM(block, REG_EAX, C0 | C2 | C3); + if (dest_reg != REG_EAX) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); + host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCHS %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FSQRT(codeblock_t *block, uop_t *uop) +static int +codegen_FDIV(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_SQRTSD_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSQRT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FTST(codeblock_t *block, uop_t *uop) +static int +codegen_FMUL(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a)) - { - host_x86_PXOR_XREG_XREG(block, REG_XMM_TEMP, REG_XMM_TEMP); - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, REG_XMM_TEMP); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FTST %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_FSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) { + host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; } -static int codegen_FADD(codeblock_t *block, uop_t *uop) +static int +codegen_FP_ENTER(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + uint32_t *branch_offset; - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_ADDSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FCOM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; - if (REG_IS_W(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - if (dest_reg != REG_EAX) - host_x86_MOV32_REG_REG(block, REG_ECX, REG_EAX); - host_x86_XOR32_REG_REG(block, REG_EAX, REG_EAX); - host_x86_COMISD_XREG_XREG(block, src_reg_a, src_reg_b); - host_x86_LAHF(block); - host_x86_AND16_REG_IMM(block, REG_EAX, C0|C2|C3); - if (dest_reg != REG_EAX) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_EAX); - host_x86_MOV32_REG_REG(block, REG_EAX, REG_ECX); - } - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FCOM %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FDIV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_DIVSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_DIVSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FDIV %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_MULSD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_FSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b) && dest_reg == src_reg_a) - { - host_x86_SUBSD_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size_a) && REG_IS_D(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBSD_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_FSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; + return 0; } -static int codegen_FP_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + uint32_t *branch_offset; - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; + host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); + host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); + branch_offset = host_x86_JZ_long(block); + host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); + host_x86_CALL(block, x86_int); + host_x86_JMP(block, codegen_exit_rout); + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); + host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); + host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); - return 0; + return 0; } -static int codegen_MMX_ENTER(codeblock_t *block, uop_t *uop) +static int +codegen_JMP(codeblock_t *block, uop_t *uop) { - uint32_t *branch_offset; + host_x86_JMP(block, uop->p); - host_x86_MOV32_REG_ABS(block, REG_ECX, &cr0); - host_x86_TEST32_REG_IMM(block, REG_ECX, 0xc); - branch_offset = host_x86_JZ_long(block); - host_x86_MOV32_ABS_IMM(block, &cpu_state.oldpc, uop->imm_data); - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, 7); - host_x86_CALL(block, x86_int); - host_x86_JMP(block, codegen_exit_rout); - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[0], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.tag[4], 0x01010101); - host_x86_MOV32_ABS_IMM(block, &cpu_state.TOP, 0); - host_x86_MOV8_ABS_IMM(block, &cpu_state.ismmx, 1); + return 0; +} +static int +codegen_JMP_DEST(codeblock_t *block, uop_t *uop) +{ + uop->p = host_x86_JMP_long(block); - return 0; + return 0; } -static int codegen_JMP(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) { - host_x86_JMP(block, uop->p); + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - return 0; -} -static int codegen_JMP_DEST(codeblock_t *block, uop_t *uop) -{ - uop->p = host_x86_JMP_long(block); - - return 0; -} - -static int codegen_LOAD_FUNC_ARG0(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_W(src_size)) - { - host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) -{ -#ifdef RECOMPILER_DEBUG - fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); - return 0; -} -static int codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); - return 0; -} - -static int codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (!REG_IS_W(src_size)) - fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); -#endif + if (REG_IS_W(src_size)) { host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); - host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t)uop->p); - host_x86_CALL(block, loadseg); - host_x86_TEST32_REG(block, REG_EAX, REG_EAX); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; + } +# ifdef RECOMPILER_DEBUG + else + fatal("codegen_LOAD_FUNC_ARG0 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG1(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG1 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG2(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG2 %02x\n", uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_LOAD_FUNC_ARG3(codeblock_t *block, uop_t *uop) +{ +# ifdef RECOMPILER_DEBUG + fatal("codegen_LOAD_FUNC_ARG3 %02x\n", uop->src_reg_a_real); +# endif + return 0; } -static int codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG0_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG0, uop->imm_data); + return 0; } -static int codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG1_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_byte); - } - else if (REG_IS_W(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_word); - } - else if (REG_IS_L(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_long); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_CALL(block, codegen_mem_load_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_Q(dest_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } - - return 0; + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, uop->imm_data); + return 0; } -static int codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_LOAD_FUNC_ARG2_IMM(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + host_x86_MOV32_STACK_IMM(block, STACK_ARG2, uop->imm_data); + return 0; +} +static int +codegen_LOAD_FUNC_ARG3_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_STACK_IMM(block, STACK_ARG3, uop->imm_data); + return 0; +} - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); +static int +codegen_LOAD_SEG(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (!REG_IS_W(src_size)) + fatal("LOAD_SEG %02x %p\n", uop->src_reg_a_real, uop->p); +# endif + host_x86_MOV16_STACK_REG(block, STACK_ARG0, src_reg); + host_x86_MOV32_STACK_IMM(block, STACK_ARG1, (uint32_t) uop->p); + host_x86_CALL(block, loadseg); + host_x86_TEST32_REG(block, REG_EAX, REG_EAX); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_LOAD_ABS(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_ABS - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } + + return 0; +} +static int +codegen_MEM_LOAD_REG(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(dest_size)) { + host_x86_CALL(block, codegen_mem_load_byte); + } else if (REG_IS_W(dest_size)) { + host_x86_CALL(block, codegen_mem_load_word); + } else if (REG_IS_L(dest_size)) { + host_x86_CALL(block, codegen_mem_load_long); + } else if (REG_IS_Q(dest_size)) { + host_x86_CALL(block, codegen_mem_load_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_LOAD_REG - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_Q(dest_size)) { host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } - return 0; + return 0; +} +static int +codegen_MEM_LOAD_SINGLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_SINGLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + + return 0; } -static int codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_LOAD_DOUBLE(codeblock_t *block, uop_t *uop) { - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); -#ifdef RECOMPILER_DEBUG - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); +# ifdef RECOMPILER_DEBUG + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - if (!REG_IS_D(dest_size)) - fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CALL(block, codegen_mem_load_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + if (!REG_IS_D(dest_size)) + fatal("MEM_LOAD_DOUBLE - %02x\n", uop->dest_reg_a_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CALL(block, codegen_mem_load_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - return 0; + return 0; } -static int codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_ABS(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); - int src_size = IREG_GET_SIZE(uop->src_reg_b_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_b_real); + int src_size = IREG_GET_SIZE(uop->src_reg_b_real); - host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - if (REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_byte); - } - else if (REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_word); - } - else if (REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); - host_x86_CALL(block, codegen_mem_store_long); - } - else if (REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_quad); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); -#endif - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_LEA_REG_IMM(block, REG_ESI, seg_reg, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_byte); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_word); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); - - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); host_x86_CALL(block, codegen_mem_store_long); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_ABS - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); - return 0; + return 0; } -static int codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +static int +codegen_MEM_STORE_REG(codeblock_t *block, uop_t *uop) { - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); - host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_single); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} -static int codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); -#ifdef RECOMPILER_DEBUG - int src_size = IREG_GET_SIZE(uop->src_reg_c_real); - - if (!REG_IS_D(src_size)) - fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); -#endif - host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); - if (uop->imm_data) - host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + if (REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_byte); + } else if (REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_word); + } else if (REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, REG_ECX, src_reg); + host_x86_CALL(block, codegen_mem_store_long); + } else if (REG_IS_Q(src_size)) { host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); - host_x86_CALL(block, codegen_mem_store_double); - host_x86_TEST32_REG(block, REG_ESI, REG_ESI); - host_x86_JNZ(block, codegen_exit_rout); - - return 0; -} - -static int codegen_MOV(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_PTR(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t)uop->p); - return 0; -} -static int codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); - } - else if (REG_IS_B(dest_size)) - { - host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size)) - { - host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); - } - else if (REG_IS_W(dest_size)) - { - host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); - } - else - fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); - - return 0; -} -static int codegen_MOVSX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOVZX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) - { - host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) - { - host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); - } - else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) - { - host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_D(dest_size) && REG_IS_L(src_size)) - { - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); - } - else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) - { - host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); - host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); - } - else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) - { - /*There is no SSE instruction to convert a 64-bit integer to a floating point value. - Instead we have to bounce the integer through memory via x87.*/ - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); - host_x87_FILDq_BASE(block, REG_ESP); - host_x87_FSTPd_BASE(block, REG_ESP); - host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } - else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) - { - host_x86_LDMXCSR(block, &cpu_state.new_fp_control); - host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); - host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) - { - uint32_t *branch_offset; - - /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ - host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); - host_x86_TEST8_REG(block, tag_reg, tag_reg); - branch_offset = host_x86_JS_long(block); - - /*There is no SSE instruction to convert a floating point value to a 64-bit integer. - Instead we have to bounce through memory via x87.*/ - host_x87_FLDCW(block, &cpu_state.new_fp_control2); - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); - host_x87_FLDd_BASE(block, REG_ESP); - host_x87_FISTPq_BASE(block, REG_ESP); - host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); - host_x87_FLDCW(block, &cpu_state.old_fp_control2); - - *branch_offset = (uint32_t)((uintptr_t)&block_write_data[block_pos] - (uintptr_t)branch_offset) - 4; - } -#ifdef RECOMPILER_DEBUG - else - fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_NOP(codeblock_t *block, uop_t *uop) -{ - return 0; -} - -static int codegen_OR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_OR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_L(dest_size) && dest_reg == src_reg) - { - host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && dest_reg == src_reg) - { - host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && dest_reg == src_reg) - { - host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PACKSSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKSSDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PACKUSWB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PADDB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PADDUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PCMPEQB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPEQD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PCMPGTD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PF2ID(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); - host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); - host_x86_LDMXCSR(block, &cpu_state.old_fp_control); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFADD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGE(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFCMPGT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMAX(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMIN(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFMUL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PFRCP(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RCPSS + iteration)*/ - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFRSQRT(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - /*TODO: This could be improved (use RSQRTSS + iteration)*/ - host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_MOV32_REG_IMM(block, REG_ECX, 1); - host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); - host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} -static int codegen_PFSUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) - { - host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); - host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); - host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PI2FD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) - { - host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); -#endif - return 0; -} - -static int codegen_PMADDWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULHW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PMULLW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); - - if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_PSUBB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PSUBUSW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} - -static int codegen_ROL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_ROR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_SAR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SAR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHL_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_CL(block, dest_reg); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_CL(block, dest_reg); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_CL(block, dest_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} -static int codegen_SHR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} -static int codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} -static int codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) -{ - host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); - return 0; -} - -static int codegen_SUB(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) - { - if (uop->dest_reg_a_real != uop->src_reg_a_real) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); - host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_SUB_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV32_REG_REG(block, dest_reg, src_reg); - host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV16_REG_REG(block, dest_reg, src_reg); - host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) - { - if (dest_reg != src_reg) - host_x86_MOV8_REG_REG(block, dest_reg, src_reg); - host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -static int codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JNS_long(block); - - return 0; -} -static int codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) -{ - int src_reg = HOST_REG_GET(uop->src_reg_a_real); - int src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(src_size)) - { - host_x86_TEST32_REG(block, src_reg, src_reg); - } - else if (REG_IS_W(src_size)) - { - host_x86_TEST16_REG(block, src_reg, src_reg); - } - else if (REG_IS_B(src_size)) - { - host_x86_TEST8_REG(block, src_reg, src_reg); - } -#ifdef RECOMPILER_DEBUG - else - fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); -#endif - uop->p = host_x86_JS_long(block); - - return 0; -} - -static int codegen_XOR(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); - - if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); - } - else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); -#endif - return 0; -} -static int codegen_XOR_IMM(codeblock_t *block, uop_t *uop) -{ - int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); - int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); - - if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); - } - else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) - { - host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); - } -#ifdef RECOMPILER_DEBUG - else - fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); -#endif - return 0; -} - -#ifdef DEBUG_EXTRA -static int codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) -{ - if (uop->imm_data > 256*256) - fatal("LOG_INSTR %08x\n", uop->imm_data); - host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); - return 0; -} -#endif - -const uOpFn uop_handlers[UOP_MAX] = -{ - [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, - [UOP_CALL_FUNC_RESULT & UOP_MASK] = codegen_CALL_FUNC_RESULT, - [UOP_CALL_INSTRUCTION_FUNC & UOP_MASK] = codegen_CALL_INSTRUCTION_FUNC, - - [UOP_JMP & UOP_MASK] = codegen_JMP, - [UOP_JMP_DEST & UOP_MASK] = codegen_JMP_DEST, - - [UOP_LOAD_SEG & UOP_MASK] = codegen_LOAD_SEG, - - [UOP_LOAD_FUNC_ARG_0 & UOP_MASK] = codegen_LOAD_FUNC_ARG0, - [UOP_LOAD_FUNC_ARG_1 & UOP_MASK] = codegen_LOAD_FUNC_ARG1, - [UOP_LOAD_FUNC_ARG_2 & UOP_MASK] = codegen_LOAD_FUNC_ARG2, - [UOP_LOAD_FUNC_ARG_3 & UOP_MASK] = codegen_LOAD_FUNC_ARG3, - - [UOP_LOAD_FUNC_ARG_0_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG0_IMM, - [UOP_LOAD_FUNC_ARG_1_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG1_IMM, - [UOP_LOAD_FUNC_ARG_2_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG2_IMM, - [UOP_LOAD_FUNC_ARG_3_IMM & UOP_MASK] = codegen_LOAD_FUNC_ARG3_IMM, - - [UOP_STORE_P_IMM & UOP_MASK] = codegen_STORE_PTR_IMM, - [UOP_STORE_P_IMM_8 & UOP_MASK] = codegen_STORE_PTR_IMM_8, - [UOP_STORE_P_IMM_16 & UOP_MASK] = codegen_STORE_PTR_IMM_16, - - [UOP_MEM_LOAD_ABS & UOP_MASK] = codegen_MEM_LOAD_ABS, - [UOP_MEM_LOAD_REG & UOP_MASK] = codegen_MEM_LOAD_REG, - [UOP_MEM_LOAD_SINGLE & UOP_MASK] = codegen_MEM_LOAD_SINGLE, - [UOP_MEM_LOAD_DOUBLE & UOP_MASK] = codegen_MEM_LOAD_DOUBLE, - - [UOP_MEM_STORE_ABS & UOP_MASK] = codegen_MEM_STORE_ABS, - [UOP_MEM_STORE_REG & UOP_MASK] = codegen_MEM_STORE_REG, - [UOP_MEM_STORE_IMM_8 & UOP_MASK] = codegen_MEM_STORE_IMM_8, - [UOP_MEM_STORE_IMM_16 & UOP_MASK] = codegen_MEM_STORE_IMM_16, - [UOP_MEM_STORE_IMM_32 & UOP_MASK] = codegen_MEM_STORE_IMM_32, - [UOP_MEM_STORE_SINGLE & UOP_MASK] = codegen_MEM_STORE_SINGLE, - [UOP_MEM_STORE_DOUBLE & UOP_MASK] = codegen_MEM_STORE_DOUBLE, - - [UOP_MOV & UOP_MASK] = codegen_MOV, - [UOP_MOV_PTR & UOP_MASK] = codegen_MOV_PTR, - [UOP_MOV_IMM & UOP_MASK] = codegen_MOV_IMM, - [UOP_MOVSX & UOP_MASK] = codegen_MOVSX, - [UOP_MOVZX & UOP_MASK] = codegen_MOVZX, - [UOP_MOV_DOUBLE_INT & UOP_MASK] = codegen_MOV_DOUBLE_INT, - [UOP_MOV_INT_DOUBLE & UOP_MASK] = codegen_MOV_INT_DOUBLE, - [UOP_MOV_INT_DOUBLE_64 & UOP_MASK] = codegen_MOV_INT_DOUBLE_64, - [UOP_MOV_REG_PTR & UOP_MASK] = codegen_MOV_REG_PTR, - [UOP_MOVZX_REG_PTR_8 & UOP_MASK] = codegen_MOVZX_REG_PTR_8, - [UOP_MOVZX_REG_PTR_16 & UOP_MASK] = codegen_MOVZX_REG_PTR_16, - - [UOP_ADD & UOP_MASK] = codegen_ADD, - [UOP_ADD_IMM & UOP_MASK] = codegen_ADD_IMM, - [UOP_ADD_LSHIFT & UOP_MASK] = codegen_ADD_LSHIFT, - [UOP_AND & UOP_MASK] = codegen_AND, - [UOP_AND_IMM & UOP_MASK] = codegen_AND_IMM, - [UOP_ANDN & UOP_MASK] = codegen_ANDN, - [UOP_OR & UOP_MASK] = codegen_OR, - [UOP_OR_IMM & UOP_MASK] = codegen_OR_IMM, - [UOP_SUB & UOP_MASK] = codegen_SUB, - [UOP_SUB_IMM & UOP_MASK] = codegen_SUB_IMM, - [UOP_XOR & UOP_MASK] = codegen_XOR, - [UOP_XOR_IMM & UOP_MASK] = codegen_XOR_IMM, - - [UOP_SAR & UOP_MASK] = codegen_SAR, - [UOP_SAR_IMM & UOP_MASK] = codegen_SAR_IMM, - [UOP_SHL & UOP_MASK] = codegen_SHL, - [UOP_SHL_IMM & UOP_MASK] = codegen_SHL_IMM, - [UOP_SHR & UOP_MASK] = codegen_SHR, - [UOP_SHR_IMM & UOP_MASK] = codegen_SHR_IMM, - [UOP_ROL & UOP_MASK] = codegen_ROL, - [UOP_ROL_IMM & UOP_MASK] = codegen_ROL_IMM, - [UOP_ROR & UOP_MASK] = codegen_ROR, - [UOP_ROR_IMM & UOP_MASK] = codegen_ROR_IMM, - - [UOP_CMP_IMM_JZ & UOP_MASK] = codegen_CMP_IMM_JZ, - - [UOP_CMP_JB & UOP_MASK] = codegen_CMP_JB, - [UOP_CMP_JNBE & UOP_MASK] = codegen_CMP_JNBE, - - [UOP_CMP_JNB_DEST & UOP_MASK] = codegen_CMP_JNB_DEST, - [UOP_CMP_JNBE_DEST & UOP_MASK] = codegen_CMP_JNBE_DEST, - [UOP_CMP_JNL_DEST & UOP_MASK] = codegen_CMP_JNL_DEST, - [UOP_CMP_JNLE_DEST & UOP_MASK] = codegen_CMP_JNLE_DEST, - [UOP_CMP_JNO_DEST & UOP_MASK] = codegen_CMP_JNO_DEST, - [UOP_CMP_JNZ_DEST & UOP_MASK] = codegen_CMP_JNZ_DEST, - [UOP_CMP_JB_DEST & UOP_MASK] = codegen_CMP_JB_DEST, - [UOP_CMP_JBE_DEST & UOP_MASK] = codegen_CMP_JBE_DEST, - [UOP_CMP_JL_DEST & UOP_MASK] = codegen_CMP_JL_DEST, - [UOP_CMP_JLE_DEST & UOP_MASK] = codegen_CMP_JLE_DEST, - [UOP_CMP_JO_DEST & UOP_MASK] = codegen_CMP_JO_DEST, - [UOP_CMP_JZ_DEST & UOP_MASK] = codegen_CMP_JZ_DEST, - - [UOP_CMP_IMM_JNZ_DEST & UOP_MASK] = codegen_CMP_IMM_JNZ_DEST, - [UOP_CMP_IMM_JZ_DEST & UOP_MASK] = codegen_CMP_IMM_JZ_DEST, - - [UOP_TEST_JNS_DEST & UOP_MASK] = codegen_TEST_JNS_DEST, - [UOP_TEST_JS_DEST & UOP_MASK] = codegen_TEST_JS_DEST, - - [UOP_FP_ENTER & UOP_MASK] = codegen_FP_ENTER, - [UOP_MMX_ENTER & UOP_MASK] = codegen_MMX_ENTER, - - [UOP_FADD & UOP_MASK] = codegen_FADD, - [UOP_FDIV & UOP_MASK] = codegen_FDIV, - [UOP_FMUL & UOP_MASK] = codegen_FMUL, - [UOP_FSUB & UOP_MASK] = codegen_FSUB, - [UOP_FCOM & UOP_MASK] = codegen_FCOM, - - [UOP_FABS & UOP_MASK] = codegen_FABS, - [UOP_FCHS & UOP_MASK] = codegen_FCHS, - [UOP_FSQRT & UOP_MASK] = codegen_FSQRT, - [UOP_FTST & UOP_MASK] = codegen_FTST, - - [UOP_PACKSSWB & UOP_MASK] = codegen_PACKSSWB, - [UOP_PACKSSDW & UOP_MASK] = codegen_PACKSSDW, - [UOP_PACKUSWB & UOP_MASK] = codegen_PACKUSWB, - - [UOP_PADDB & UOP_MASK] = codegen_PADDB, - [UOP_PADDW & UOP_MASK] = codegen_PADDW, - [UOP_PADDD & UOP_MASK] = codegen_PADDD, - [UOP_PADDSB & UOP_MASK] = codegen_PADDSB, - [UOP_PADDSW & UOP_MASK] = codegen_PADDSW, - [UOP_PADDUSB & UOP_MASK] = codegen_PADDUSB, - [UOP_PADDUSW & UOP_MASK] = codegen_PADDUSW, - - [UOP_PCMPEQB & UOP_MASK] = codegen_PCMPEQB, - [UOP_PCMPEQW & UOP_MASK] = codegen_PCMPEQW, - [UOP_PCMPEQD & UOP_MASK] = codegen_PCMPEQD, - [UOP_PCMPGTB & UOP_MASK] = codegen_PCMPGTB, - [UOP_PCMPGTW & UOP_MASK] = codegen_PCMPGTW, - [UOP_PCMPGTD & UOP_MASK] = codegen_PCMPGTD, - - [UOP_PF2ID & UOP_MASK] = codegen_PF2ID, - [UOP_PFADD & UOP_MASK] = codegen_PFADD, - [UOP_PFCMPEQ & UOP_MASK] = codegen_PFCMPEQ, - [UOP_PFCMPGE & UOP_MASK] = codegen_PFCMPGE, - [UOP_PFCMPGT & UOP_MASK] = codegen_PFCMPGT, - [UOP_PFMAX & UOP_MASK] = codegen_PFMAX, - [UOP_PFMIN & UOP_MASK] = codegen_PFMIN, - [UOP_PFMUL & UOP_MASK] = codegen_PFMUL, - [UOP_PFRCP & UOP_MASK] = codegen_PFRCP, - [UOP_PFRSQRT & UOP_MASK] = codegen_PFRSQRT, - [UOP_PFSUB & UOP_MASK] = codegen_PFSUB, - [UOP_PI2FD & UOP_MASK] = codegen_PI2FD, - - [UOP_PMADDWD & UOP_MASK] = codegen_PMADDWD, - [UOP_PMULHW & UOP_MASK] = codegen_PMULHW, - [UOP_PMULLW & UOP_MASK] = codegen_PMULLW, - - [UOP_PSLLW_IMM & UOP_MASK] = codegen_PSLLW_IMM, - [UOP_PSLLD_IMM & UOP_MASK] = codegen_PSLLD_IMM, - [UOP_PSLLQ_IMM & UOP_MASK] = codegen_PSLLQ_IMM, - [UOP_PSRAW_IMM & UOP_MASK] = codegen_PSRAW_IMM, - [UOP_PSRAD_IMM & UOP_MASK] = codegen_PSRAD_IMM, - [UOP_PSRAQ_IMM & UOP_MASK] = codegen_PSRAQ_IMM, - [UOP_PSRLW_IMM & UOP_MASK] = codegen_PSRLW_IMM, - [UOP_PSRLD_IMM & UOP_MASK] = codegen_PSRLD_IMM, - [UOP_PSRLQ_IMM & UOP_MASK] = codegen_PSRLQ_IMM, - - [UOP_PSUBB & UOP_MASK] = codegen_PSUBB, - [UOP_PSUBW & UOP_MASK] = codegen_PSUBW, - [UOP_PSUBD & UOP_MASK] = codegen_PSUBD, - [UOP_PSUBSB & UOP_MASK] = codegen_PSUBSB, - [UOP_PSUBSW & UOP_MASK] = codegen_PSUBSW, - [UOP_PSUBUSB & UOP_MASK] = codegen_PSUBUSB, - [UOP_PSUBUSW & UOP_MASK] = codegen_PSUBUSW, - - [UOP_PUNPCKHBW & UOP_MASK] = codegen_PUNPCKHBW, - [UOP_PUNPCKHWD & UOP_MASK] = codegen_PUNPCKHWD, - [UOP_PUNPCKHDQ & UOP_MASK] = codegen_PUNPCKHDQ, - [UOP_PUNPCKLBW & UOP_MASK] = codegen_PUNPCKLBW, - [UOP_PUNPCKLWD & UOP_MASK] = codegen_PUNPCKLWD, - [UOP_PUNPCKLDQ & UOP_MASK] = codegen_PUNPCKLDQ, - - [UOP_NOP_BARRIER & UOP_MASK] = codegen_NOP, - -#ifdef DEBUG_EXTRA - [UOP_LOG_INSTR & UOP_MASK] = codegen_LOG_INSTR -#endif + host_x86_CALL(block, codegen_mem_store_quad); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MEM_STORE_REG - %02x\n", uop->src_reg_b_real); +# endif + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_STORE_IMM_8(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV8_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_byte); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_IMM_16(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV16_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_word); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_IMM_32(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real); + + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + host_x86_MOV32_REG_IMM(block, REG_ECX, uop->imm_data); + host_x86_CALL(block, codegen_mem_store_long); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MEM_STORE_SINGLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_SINGLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_CVTSD2SS_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_single); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} +static int +codegen_MEM_STORE_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int seg_reg = HOST_REG_GET(uop->src_reg_a_real), addr_reg = HOST_REG_GET(uop->src_reg_b_real), src_reg = HOST_REG_GET(uop->src_reg_c_real); +# ifdef RECOMPILER_DEBUG + int src_size = IREG_GET_SIZE(uop->src_reg_c_real); + + if (!REG_IS_D(src_size)) + fatal("MEM_STORE_DOUBLE - %02x\n", uop->src_reg_b_real); +# endif + host_x86_LEA_REG_REG(block, REG_ESI, seg_reg, addr_reg); + if (uop->imm_data) + host_x86_ADD32_REG_IMM(block, REG_ESI, uop->imm_data); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg); + host_x86_CALL(block, codegen_mem_store_double); + host_x86_TEST32_REG(block, REG_ESI, REG_ESI); + host_x86_JNZ(block, codegen_exit_rout); + + return 0; +} + +static int +codegen_MOV(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_D(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_IMM %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_PTR(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_REG_IMM(block, uop->dest_reg_a_real, (uint32_t) uop->p); + return 0; +} +static int +codegen_MOV_REG_PTR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOV32_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOV_REG_PTR %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_8(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_8(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOVZX_REG_ABS_16_8(block, dest_reg, uop->p); + } else if (REG_IS_B(dest_size)) { + host_x86_MOV8_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_8 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVZX_REG_PTR_16(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size)) { + host_x86_MOVZX_REG_ABS_32_16(block, dest_reg, uop->p); + } else if (REG_IS_W(dest_size)) { + host_x86_MOV16_REG_ABS(block, dest_reg, uop->p); + } else + fatal("MOVZX_REG_PTR_16 %02x\n", uop->dest_reg_a_real); + + return 0; +} +static int +codegen_MOVSX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVSX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVSX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOVZX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_L(src_size)) { + host_x86_MOVD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_Q(src_size)) { + host_x86_MOVD_REG_XREG(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVZX_REG_32_16(block, dest_reg, src_reg); + } else if (REG_IS_L(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_32_8(block, dest_reg, src_reg); + } else if (REG_IS_W(dest_size) && REG_IS_B(src_size)) { + host_x86_MOVZX_REG_16_8(block, dest_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOVZX %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_MOV_DOUBLE_INT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_D(dest_size) && REG_IS_L(src_size)) { + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, src_reg); + } else if (REG_IS_D(dest_size) && REG_IS_W(src_size)) { + host_x86_MOVSX_REG_32_16(block, REG_ECX, src_reg); + host_x86_CVTSI2SD_XREG_REG(block, dest_reg, REG_ECX); + } else if (REG_IS_D(dest_size) && REG_IS_Q(src_size)) { + /*There is no SSE instruction to convert a 64-bit integer to a floating point value. + Instead we have to bounce the integer through memory via x87.*/ + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FILDq_BASE(block, REG_ESP); + host_x87_FSTPd_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_DOUBLE_INT %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_MOV_INT_DOUBLE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, dest_reg, src_reg); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } else if (REG_IS_W(dest_size) && REG_IS_D(src_size)) { + host_x86_LDMXCSR(block, &cpu_state.new_fp_control); + host_x86_CVTSD2SI_REG_XREG(block, REG_ECX, src_reg); + host_x86_MOV16_REG_REG(block, dest_reg, REG_ECX); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_MOV_INT_DOUBLE_64(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), src_64_reg = HOST_REG_GET(uop->src_reg_b_real), tag_reg = HOST_REG_GET(uop->src_reg_c_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real), src_64_size = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_D(src_size) && REG_IS_Q(src_64_size)) { + uint32_t *branch_offset; + + /*If TAG_UINT64 is set then the source is MM[]. Otherwise it is a double in ST()*/ + host_x86_MOVQ_XREG_XREG(block, dest_reg, src_64_reg); + host_x86_TEST8_REG(block, tag_reg, tag_reg); + branch_offset = host_x86_JS_long(block); + + /*There is no SSE instruction to convert a floating point value to a 64-bit integer. + Instead we have to bounce through memory via x87.*/ + host_x87_FLDCW(block, &cpu_state.new_fp_control2); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, 0, src_reg); + host_x87_FLDd_BASE(block, REG_ESP); + host_x87_FISTPq_BASE(block, REG_ESP); + host_x86_MOVQ_XREG_BASE_OFFSET(block, dest_reg, REG_ESP, 0); + host_x87_FLDCW(block, &cpu_state.old_fp_control2); + + *branch_offset = (uint32_t) ((uintptr_t) &block_write_data[block_pos] - (uintptr_t) branch_offset) - 4; + } +# ifdef RECOMPILER_DEBUG + else + fatal("MOV_INT_DOUBLE_64 %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_NOP(codeblock_t *block, uop_t *uop) +{ + return 0; +} + +static int +codegen_OR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_POR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_OR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_OR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_L(dest_size) && dest_reg == src_reg) { + host_x86_OR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && dest_reg == src_reg) { + host_x86_OR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && dest_reg == src_reg) { + host_x86_OR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("OR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PACKSSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKSSDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKSSDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKSSDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PACKUSWB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PACKUSWB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PACKUSWB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PADDB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PADDUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PADDUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PADDUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PCMPEQB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPEQD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPEQD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPEQD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PCMPGTD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PCMPGTD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PCMPGTD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PF2ID(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_LDMXCSR(block, &cpu_state.trunc_fp_control); + host_x86_CVTPS2DQ_XREG_XREG(block, dest_reg, src_reg_a); + host_x86_LDMXCSR(block, &cpu_state.old_fp_control); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PF2ID %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFADD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_ADDPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFADD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPEQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_EQ); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPEQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGE(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLT); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGE %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFCMPGT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_CMPPS_XREG_XREG(block, dest_reg, src_reg_b, CMPPS_NLE); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFCMPGT %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMAX(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MAXPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMAX %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMIN(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MINPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMIN %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFMUL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_MULPS_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFMUL %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PFRCP(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RCPSS + iteration)*/ + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRCP %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFRSQRT(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + /*TODO: This could be improved (use RSQRTSS + iteration)*/ + host_x86_SQRTSS_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_MOV32_REG_IMM(block, REG_ECX, 1); + host_x86_CVTSI2SS_XREG_REG(block, dest_reg, REG_ECX); + host_x86_DIVSS_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + host_x86_UNPCKLPS_XREG_XREG(block, dest_reg, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFRSQRT %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} +static int +codegen_PFSUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_SUBPS_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b)) { + host_x86_MOVQ_XREG_XREG(block, REG_XMM_TEMP, src_reg_a); + host_x86_SUBPS_XREG_XREG(block, REG_XMM_TEMP, src_reg_b); + host_x86_MOVQ_XREG_XREG(block, dest_reg, REG_XMM_TEMP); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PFSUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PI2FD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a)) { + host_x86_CVTDQ2PS_XREG_XREG(block, dest_reg, src_reg_a); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PI2FD %02x %02x\n", uop->dest_reg_a_real); +# endif + return 0; +} + +static int +codegen_PMADDWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMADDWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULHW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULHW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULHW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PMULLW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PMULLW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PMULLW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PSLLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSLLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSLLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSLLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRAQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRAQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRAQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLW_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLW_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLW_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLD_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLD_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLD_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_PSRLQ_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real); + + if (REG_IS_Q(dest_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSRLQ_XREG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSRLQ_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_PSUBB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSB_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PSUBUSW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PSUBUSW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PSUBUSW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_PUNPCKHBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKHDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + host_x86_PSHUFD_XREG_XREG_IMM(block, dest_reg, dest_reg, 0xee); /*0xee = move top 64-bits to low 64-bits*/ + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKHDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLBW(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLBW_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLBW %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLWD(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLWD_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLWD %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_PUNPCKLDQ(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PUNPCKLDQ_XREG_XREG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("PUNPCKLDQ %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} + +static int +codegen_ROL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_ROR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_ROR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_ROR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_ROR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("ROR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_SAR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SAR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SAR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SAR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SAR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SAR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHL_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHL32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHL16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHL8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHL_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real), shift_reg = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + host_x86_MOV32_REG_REG(block, REG_ECX, shift_reg); + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_CL(block, dest_reg); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_CL(block, dest_reg); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_CL(block, dest_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} +static int +codegen_SHR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SHR32_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SHR16_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SHR8_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SHR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_STORE_PTR_IMM(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV32_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int +codegen_STORE_PTR_IMM_8(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV8_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} +static int +codegen_STORE_PTR_IMM_16(codeblock_t *block, uop_t *uop) +{ + host_x86_MOV16_ABS_IMM(block, uop->p, uop->imm_data); + return 0; +} + +static int +codegen_SUB(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_a = HOST_REG_GET(uop->src_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b)) { + if (uop->dest_reg_a_real != uop->src_reg_a_real) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg_a); + host_x86_SUB8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_SUB_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg = HOST_REG_GET(uop->src_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV32_REG_REG(block, dest_reg, src_reg); + host_x86_SUB32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV16_REG_REG(block, dest_reg, src_reg); + host_x86_SUB16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size)) { + if (dest_reg != src_reg) + host_x86_MOV8_REG_REG(block, dest_reg, src_reg); + host_x86_SUB8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("SUB_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +static int +codegen_TEST_JNS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JNS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JNS_long(block); + + return 0; +} +static int +codegen_TEST_JS_DEST(codeblock_t *block, uop_t *uop) +{ + int src_reg = HOST_REG_GET(uop->src_reg_a_real); + int src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(src_size)) { + host_x86_TEST32_REG(block, src_reg, src_reg); + } else if (REG_IS_W(src_size)) { + host_x86_TEST16_REG(block, src_reg, src_reg); + } else if (REG_IS_B(src_size)) { + host_x86_TEST8_REG(block, src_reg, src_reg); + } +# ifdef RECOMPILER_DEBUG + else + fatal("TEST_JS_DEST %02x\n", uop->src_reg_a_real); +# endif + uop->p = host_x86_JS_long(block); + + return 0; +} + +static int +codegen_XOR(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real), src_reg_b = HOST_REG_GET(uop->src_reg_b_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size_a = IREG_GET_SIZE(uop->src_reg_a_real), src_size_b = IREG_GET_SIZE(uop->src_reg_b_real); + + if (REG_IS_Q(dest_size) && REG_IS_Q(src_size_a) && REG_IS_Q(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_PXOR_XREG_XREG(block, dest_reg, src_reg_b); + } else if (REG_IS_L(dest_size) && REG_IS_L(src_size_a) && REG_IS_L(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size_a) && REG_IS_W(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_REG(block, dest_reg, src_reg_b); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size_a) && REG_IS_B(src_size_b) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_REG(block, dest_reg, src_reg_b); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR %02x %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real, uop->src_reg_b_real); +# endif + return 0; +} +static int +codegen_XOR_IMM(codeblock_t *block, uop_t *uop) +{ + int dest_reg = HOST_REG_GET(uop->dest_reg_a_real); + int dest_size = IREG_GET_SIZE(uop->dest_reg_a_real), src_size = IREG_GET_SIZE(uop->src_reg_a_real); + + if (REG_IS_L(dest_size) && REG_IS_L(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR32_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_W(dest_size) && REG_IS_W(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR16_REG_IMM(block, dest_reg, uop->imm_data); + } else if (REG_IS_B(dest_size) && REG_IS_B(src_size) && uop->dest_reg_a_real == uop->src_reg_a_real) { + host_x86_XOR8_REG_IMM(block, dest_reg, uop->imm_data); + } +# ifdef RECOMPILER_DEBUG + else + fatal("XOR_IMM %02x %02x\n", uop->dest_reg_a_real, uop->src_reg_a_real); +# endif + return 0; +} + +# ifdef DEBUG_EXTRA +static int +codegen_LOG_INSTR(codeblock_t *block, uop_t *uop) +{ + if (uop->imm_data > 256 * 256) + fatal("LOG_INSTR %08x\n", uop->imm_data); + host_x86_INC32_ABS(block, &instr_counts[uop->imm_data]); + return 0; +} +# endif + +const uOpFn uop_handlers[UOP_MAX] = { + [UOP_CALL_FUNC & UOP_MASK] = codegen_CALL_FUNC, + [UOP_CALL_FUNC_RESULT & + UOP_MASK] + = codegen_CALL_FUNC_RESULT, + [UOP_CALL_INSTRUCTION_FUNC & + UOP_MASK] + = codegen_CALL_INSTRUCTION_FUNC, + + [UOP_JMP & + UOP_MASK] + = codegen_JMP, + [UOP_JMP_DEST & + UOP_MASK] + = codegen_JMP_DEST, + + [UOP_LOAD_SEG & + UOP_MASK] + = codegen_LOAD_SEG, + + [UOP_LOAD_FUNC_ARG_0 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0, + [UOP_LOAD_FUNC_ARG_1 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1, + [UOP_LOAD_FUNC_ARG_2 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2, + [UOP_LOAD_FUNC_ARG_3 & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3, + + [UOP_LOAD_FUNC_ARG_0_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG0_IMM, + [UOP_LOAD_FUNC_ARG_1_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG1_IMM, + [UOP_LOAD_FUNC_ARG_2_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG2_IMM, + [UOP_LOAD_FUNC_ARG_3_IMM & + UOP_MASK] + = codegen_LOAD_FUNC_ARG3_IMM, + + [UOP_STORE_P_IMM & + UOP_MASK] + = codegen_STORE_PTR_IMM, + [UOP_STORE_P_IMM_8 & + UOP_MASK] + = codegen_STORE_PTR_IMM_8, + [UOP_STORE_P_IMM_16 & + UOP_MASK] + = codegen_STORE_PTR_IMM_16, + + [UOP_MEM_LOAD_ABS & + UOP_MASK] + = codegen_MEM_LOAD_ABS, + [UOP_MEM_LOAD_REG & + UOP_MASK] + = codegen_MEM_LOAD_REG, + [UOP_MEM_LOAD_SINGLE & + UOP_MASK] + = codegen_MEM_LOAD_SINGLE, + [UOP_MEM_LOAD_DOUBLE & + UOP_MASK] + = codegen_MEM_LOAD_DOUBLE, + + [UOP_MEM_STORE_ABS & + UOP_MASK] + = codegen_MEM_STORE_ABS, + [UOP_MEM_STORE_REG & + UOP_MASK] + = codegen_MEM_STORE_REG, + [UOP_MEM_STORE_IMM_8 & + UOP_MASK] + = codegen_MEM_STORE_IMM_8, + [UOP_MEM_STORE_IMM_16 & + UOP_MASK] + = codegen_MEM_STORE_IMM_16, + [UOP_MEM_STORE_IMM_32 & + UOP_MASK] + = codegen_MEM_STORE_IMM_32, + [UOP_MEM_STORE_SINGLE & + UOP_MASK] + = codegen_MEM_STORE_SINGLE, + [UOP_MEM_STORE_DOUBLE & + UOP_MASK] + = codegen_MEM_STORE_DOUBLE, + + [UOP_MOV & + UOP_MASK] + = codegen_MOV, + [UOP_MOV_PTR & + UOP_MASK] + = codegen_MOV_PTR, + [UOP_MOV_IMM & + UOP_MASK] + = codegen_MOV_IMM, + [UOP_MOVSX & + UOP_MASK] + = codegen_MOVSX, + [UOP_MOVZX & + UOP_MASK] + = codegen_MOVZX, + [UOP_MOV_DOUBLE_INT & + UOP_MASK] + = codegen_MOV_DOUBLE_INT, + [UOP_MOV_INT_DOUBLE & + UOP_MASK] + = codegen_MOV_INT_DOUBLE, + [UOP_MOV_INT_DOUBLE_64 & + UOP_MASK] + = codegen_MOV_INT_DOUBLE_64, + [UOP_MOV_REG_PTR & + UOP_MASK] + = codegen_MOV_REG_PTR, + [UOP_MOVZX_REG_PTR_8 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_8, + [UOP_MOVZX_REG_PTR_16 & + UOP_MASK] + = codegen_MOVZX_REG_PTR_16, + + [UOP_ADD & + UOP_MASK] + = codegen_ADD, + [UOP_ADD_IMM & + UOP_MASK] + = codegen_ADD_IMM, + [UOP_ADD_LSHIFT & + UOP_MASK] + = codegen_ADD_LSHIFT, + [UOP_AND & + UOP_MASK] + = codegen_AND, + [UOP_AND_IMM & + UOP_MASK] + = codegen_AND_IMM, + [UOP_ANDN & + UOP_MASK] + = codegen_ANDN, + [UOP_OR & + UOP_MASK] + = codegen_OR, + [UOP_OR_IMM & + UOP_MASK] + = codegen_OR_IMM, + [UOP_SUB & + UOP_MASK] + = codegen_SUB, + [UOP_SUB_IMM & + UOP_MASK] + = codegen_SUB_IMM, + [UOP_XOR & + UOP_MASK] + = codegen_XOR, + [UOP_XOR_IMM & + UOP_MASK] + = codegen_XOR_IMM, + + [UOP_SAR & + UOP_MASK] + = codegen_SAR, + [UOP_SAR_IMM & + UOP_MASK] + = codegen_SAR_IMM, + [UOP_SHL & + UOP_MASK] + = codegen_SHL, + [UOP_SHL_IMM & + UOP_MASK] + = codegen_SHL_IMM, + [UOP_SHR & + UOP_MASK] + = codegen_SHR, + [UOP_SHR_IMM & + UOP_MASK] + = codegen_SHR_IMM, + [UOP_ROL & + UOP_MASK] + = codegen_ROL, + [UOP_ROL_IMM & + UOP_MASK] + = codegen_ROL_IMM, + [UOP_ROR & + UOP_MASK] + = codegen_ROR, + [UOP_ROR_IMM & + UOP_MASK] + = codegen_ROR_IMM, + + [UOP_CMP_IMM_JZ & + UOP_MASK] + = codegen_CMP_IMM_JZ, + + [UOP_CMP_JB & + UOP_MASK] + = codegen_CMP_JB, + [UOP_CMP_JNBE & + UOP_MASK] + = codegen_CMP_JNBE, + + [UOP_CMP_JNB_DEST & + UOP_MASK] + = codegen_CMP_JNB_DEST, + [UOP_CMP_JNBE_DEST & + UOP_MASK] + = codegen_CMP_JNBE_DEST, + [UOP_CMP_JNL_DEST & + UOP_MASK] + = codegen_CMP_JNL_DEST, + [UOP_CMP_JNLE_DEST & + UOP_MASK] + = codegen_CMP_JNLE_DEST, + [UOP_CMP_JNO_DEST & + UOP_MASK] + = codegen_CMP_JNO_DEST, + [UOP_CMP_JNZ_DEST & + UOP_MASK] + = codegen_CMP_JNZ_DEST, + [UOP_CMP_JB_DEST & + UOP_MASK] + = codegen_CMP_JB_DEST, + [UOP_CMP_JBE_DEST & + UOP_MASK] + = codegen_CMP_JBE_DEST, + [UOP_CMP_JL_DEST & + UOP_MASK] + = codegen_CMP_JL_DEST, + [UOP_CMP_JLE_DEST & + UOP_MASK] + = codegen_CMP_JLE_DEST, + [UOP_CMP_JO_DEST & + UOP_MASK] + = codegen_CMP_JO_DEST, + [UOP_CMP_JZ_DEST & + UOP_MASK] + = codegen_CMP_JZ_DEST, + + [UOP_CMP_IMM_JNZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JNZ_DEST, + [UOP_CMP_IMM_JZ_DEST & + UOP_MASK] + = codegen_CMP_IMM_JZ_DEST, + + [UOP_TEST_JNS_DEST & + UOP_MASK] + = codegen_TEST_JNS_DEST, + [UOP_TEST_JS_DEST & + UOP_MASK] + = codegen_TEST_JS_DEST, + + [UOP_FP_ENTER & + UOP_MASK] + = codegen_FP_ENTER, + [UOP_MMX_ENTER & + UOP_MASK] + = codegen_MMX_ENTER, + + [UOP_FADD & + UOP_MASK] + = codegen_FADD, + [UOP_FDIV & + UOP_MASK] + = codegen_FDIV, + [UOP_FMUL & + UOP_MASK] + = codegen_FMUL, + [UOP_FSUB & + UOP_MASK] + = codegen_FSUB, + [UOP_FCOM & + UOP_MASK] + = codegen_FCOM, + + [UOP_FABS & + UOP_MASK] + = codegen_FABS, + [UOP_FCHS & + UOP_MASK] + = codegen_FCHS, + [UOP_FSQRT & + UOP_MASK] + = codegen_FSQRT, + [UOP_FTST & + UOP_MASK] + = codegen_FTST, + + [UOP_PACKSSWB & + UOP_MASK] + = codegen_PACKSSWB, + [UOP_PACKSSDW & + UOP_MASK] + = codegen_PACKSSDW, + [UOP_PACKUSWB & + UOP_MASK] + = codegen_PACKUSWB, + + [UOP_PADDB & + UOP_MASK] + = codegen_PADDB, + [UOP_PADDW & + UOP_MASK] + = codegen_PADDW, + [UOP_PADDD & + UOP_MASK] + = codegen_PADDD, + [UOP_PADDSB & + UOP_MASK] + = codegen_PADDSB, + [UOP_PADDSW & + UOP_MASK] + = codegen_PADDSW, + [UOP_PADDUSB & + UOP_MASK] + = codegen_PADDUSB, + [UOP_PADDUSW & + UOP_MASK] + = codegen_PADDUSW, + + [UOP_PCMPEQB & + UOP_MASK] + = codegen_PCMPEQB, + [UOP_PCMPEQW & + UOP_MASK] + = codegen_PCMPEQW, + [UOP_PCMPEQD & + UOP_MASK] + = codegen_PCMPEQD, + [UOP_PCMPGTB & + UOP_MASK] + = codegen_PCMPGTB, + [UOP_PCMPGTW & + UOP_MASK] + = codegen_PCMPGTW, + [UOP_PCMPGTD & + UOP_MASK] + = codegen_PCMPGTD, + + [UOP_PF2ID & + UOP_MASK] + = codegen_PF2ID, + [UOP_PFADD & + UOP_MASK] + = codegen_PFADD, + [UOP_PFCMPEQ & + UOP_MASK] + = codegen_PFCMPEQ, + [UOP_PFCMPGE & + UOP_MASK] + = codegen_PFCMPGE, + [UOP_PFCMPGT & + UOP_MASK] + = codegen_PFCMPGT, + [UOP_PFMAX & + UOP_MASK] + = codegen_PFMAX, + [UOP_PFMIN & + UOP_MASK] + = codegen_PFMIN, + [UOP_PFMUL & + UOP_MASK] + = codegen_PFMUL, + [UOP_PFRCP & + UOP_MASK] + = codegen_PFRCP, + [UOP_PFRSQRT & + UOP_MASK] + = codegen_PFRSQRT, + [UOP_PFSUB & + UOP_MASK] + = codegen_PFSUB, + [UOP_PI2FD & + UOP_MASK] + = codegen_PI2FD, + + [UOP_PMADDWD & + UOP_MASK] + = codegen_PMADDWD, + [UOP_PMULHW & + UOP_MASK] + = codegen_PMULHW, + [UOP_PMULLW & + UOP_MASK] + = codegen_PMULLW, + + [UOP_PSLLW_IMM & + UOP_MASK] + = codegen_PSLLW_IMM, + [UOP_PSLLD_IMM & + UOP_MASK] + = codegen_PSLLD_IMM, + [UOP_PSLLQ_IMM & + UOP_MASK] + = codegen_PSLLQ_IMM, + [UOP_PSRAW_IMM & + UOP_MASK] + = codegen_PSRAW_IMM, + [UOP_PSRAD_IMM & + UOP_MASK] + = codegen_PSRAD_IMM, + [UOP_PSRAQ_IMM & + UOP_MASK] + = codegen_PSRAQ_IMM, + [UOP_PSRLW_IMM & + UOP_MASK] + = codegen_PSRLW_IMM, + [UOP_PSRLD_IMM & + UOP_MASK] + = codegen_PSRLD_IMM, + [UOP_PSRLQ_IMM & + UOP_MASK] + = codegen_PSRLQ_IMM, + + [UOP_PSUBB & + UOP_MASK] + = codegen_PSUBB, + [UOP_PSUBW & + UOP_MASK] + = codegen_PSUBW, + [UOP_PSUBD & + UOP_MASK] + = codegen_PSUBD, + [UOP_PSUBSB & + UOP_MASK] + = codegen_PSUBSB, + [UOP_PSUBSW & + UOP_MASK] + = codegen_PSUBSW, + [UOP_PSUBUSB & + UOP_MASK] + = codegen_PSUBUSB, + [UOP_PSUBUSW & + UOP_MASK] + = codegen_PSUBUSW, + + [UOP_PUNPCKHBW & + UOP_MASK] + = codegen_PUNPCKHBW, + [UOP_PUNPCKHWD & + UOP_MASK] + = codegen_PUNPCKHWD, + [UOP_PUNPCKHDQ & + UOP_MASK] + = codegen_PUNPCKHDQ, + [UOP_PUNPCKLBW & + UOP_MASK] + = codegen_PUNPCKLBW, + [UOP_PUNPCKLWD & + UOP_MASK] + = codegen_PUNPCKLWD, + [UOP_PUNPCKLDQ & + UOP_MASK] + = codegen_PUNPCKLDQ, + + [UOP_NOP_BARRIER & + UOP_MASK] + = codegen_NOP, + +# ifdef DEBUG_EXTRA + [UOP_LOG_INSTR & + UOP_MASK] + = codegen_LOG_INSTR +# endif }; -void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_8(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV8_REG_ABS(block, host_reg, p); + host_x86_MOV8_REG_ABS(block, host_reg, p); } -void codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_16(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV16_REG_ABS(block, host_reg, p); + host_x86_MOV16_REG_ABS(block, host_reg, p); } -void codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_32(codeblock_t *block, int host_reg, void *p) { - host_x86_MOV32_REG_ABS(block, host_reg, p); + host_x86_MOV32_REG_ABS(block, host_reg, p); } -void codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_pointer(codeblock_t *block, int host_reg, void *p) { - codegen_direct_read_32(block, host_reg, p); + codegen_direct_read_32(block, host_reg, p); } -void codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_64(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) +void +codegen_direct_read_double(codeblock_t *block, int host_reg, void *p) { - host_x86_MOVQ_XREG_ABS(block, host_reg, p); + host_x86_MOVQ_XREG_ABS(block, host_reg, p); } -void codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_8(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_REG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 0); } -void codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_64(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } -void codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) +void +codegen_direct_read_st_double(codeblock_t *block, int host_reg, void *base, int reg_idx) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_XREG_ABS_REG_REG_SHIFT(block, host_reg, offset, REG_EBP, REG_ECX, 3); } -void codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_8(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV8_ABS_REG(block, p, host_reg); + host_x86_MOV8_ABS_REG(block, p, host_reg); } -void codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_16(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV16_ABS_REG(block, p, host_reg); + host_x86_MOV16_ABS_REG(block, p, host_reg); } -void codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_32(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); + host_x86_MOV32_ABS_REG(block, p, host_reg); } -void codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_64(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_double(codeblock_t *block, void *p, int host_reg) { - host_x86_MOVQ_ABS_XREG(block, p, host_reg); + host_x86_MOVQ_ABS_XREG(block, p, host_reg); } -void codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_8(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOV8_ABS_REG_REG_SHIFT_REG(block, offset, REG_EBP, REG_ECX, 0, host_reg); } -void codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_64(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) +void +codegen_direct_write_st_double(codeblock_t *block, void *base, int reg_idx, int host_reg) { - int offset = (uintptr_t)base - (((uintptr_t)&cpu_state) + 128); + int offset = (uintptr_t) base - (((uintptr_t) &cpu_state) + 128); - host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); - host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); - host_x86_AND32_REG_IMM(block, REG_ECX, 7); - host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); + host_x86_MOV32_REG_BASE_OFFSET(block, REG_ECX, REG_ESP, IREG_TOP_diff_stack_offset); + host_x86_ADD32_REG_IMM(block, REG_ECX, reg_idx); + host_x86_AND32_REG_IMM(block, REG_ECX, 7); + host_x86_MOVQ_ABS_REG_REG_SHIFT_XREG(block, offset, REG_EBP, REG_ECX, 3, host_reg); } -void codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) +void +codegen_direct_write_ptr(codeblock_t *block, void *p, int host_reg) { - host_x86_MOV32_ABS_REG(block, p, host_reg); + host_x86_MOV32_ABS_REG(block, p, host_reg); } -void codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_16_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV16_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_32_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOV32_REG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_pointer_stack(codeblock_t *block, int host_reg, int stack_offset) { - codegen_direct_read_32_stack(block, host_reg, stack_offset); + codegen_direct_read_32_stack(block, host_reg, stack_offset); } -void codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_64_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) +void +codegen_direct_read_double_stack(codeblock_t *block, int host_reg, int stack_offset) { - host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); + host_x86_MOVQ_XREG_BASE_OFFSET(block, host_reg, REG_ESP, stack_offset); } -void codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_32_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOV32_BASE_OFFSET_REG(block, REG_ESP, stack_offset, host_reg); } -void codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_64_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); } -void codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) +void +codegen_direct_write_double_stack(codeblock_t *block, int stack_offset, int host_reg) { - host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); + host_x86_MOVQ_BASE_OFFSET_XREG(block, REG_ESP, stack_offset, host_reg); } -void codegen_set_jump_dest(codeblock_t *block, void *p) +void +codegen_set_jump_dest(codeblock_t *block, void *p) { - *(uint32_t *)p = (uintptr_t)&block_write_data[block_pos] - ((uintptr_t)p + 4); + *(uint32_t *) p = (uintptr_t) &block_write_data[block_pos] - ((uintptr_t) p + 4); } -void codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) +void +codegen_direct_write_8_imm(codeblock_t *block, void *p, uint8_t imm_data) { - host_x86_MOV8_ABS_IMM(block, p, imm_data); + host_x86_MOV8_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) +void +codegen_direct_write_16_imm(codeblock_t *block, void *p, uint16_t imm_data) { - host_x86_MOV16_ABS_IMM(block, p, imm_data); + host_x86_MOV16_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) +void +codegen_direct_write_32_imm(codeblock_t *block, void *p, uint32_t imm_data) { - host_x86_MOV32_ABS_IMM(block, p, imm_data); + host_x86_MOV32_ABS_IMM(block, p, imm_data); } -void codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) +void +codegen_direct_write_32_imm_stack(codeblock_t *block, int stack_offset, uint32_t imm_data) { - host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); + host_x86_MOV32_BASE_OFFSET_IMM(block, REG_ESP, stack_offset, imm_data); } #endif diff --git a/src/codegen_new/codegen_block.c b/src/codegen_new/codegen_block.c index 283faf140..c519b34d2 100644 --- a/src/codegen_new/codegen_block.c +++ b/src/codegen_new/codegen_block.c @@ -21,39 +21,39 @@ uint8_t *block_write_data = NULL; -int codegen_flat_ds, codegen_flat_ss; -int mmx_ebx_ecx_loaded; -int codegen_flags_changed = 0; -int codegen_fpu_entered = 0; -int codegen_mmx_entered = 0; -int codegen_fpu_loaded_iq[8]; -x86seg *op_ea_seg; -int op_ssegs; +int codegen_flat_ds, codegen_flat_ss; +int mmx_ebx_ecx_loaded; +int codegen_flags_changed = 0; +int codegen_fpu_entered = 0; +int codegen_mmx_entered = 0; +int codegen_fpu_loaded_iq[8]; +x86seg *op_ea_seg; +int op_ssegs; uint32_t op_old_pc; uint32_t recomp_page = -1; -int block_current = 0; +int block_current = 0; static int block_num; -int block_pos; +int block_pos; uint32_t codegen_endpc; -int codegen_block_cycles; +int codegen_block_cycles; static int codegen_block_ins; static int codegen_block_full_ins; static uint32_t last_op32; -static x86seg *last_ea_seg; -static int last_ssegs; +static x86seg *last_ea_seg; +static int last_ssegs; #ifdef DEBUG_EXTRA -uint32_t instr_counts[256*256]; +uint32_t instr_counts[256 * 256]; #endif static uint16_t block_free_list; -static void delete_block(codeblock_t *block); -static void delete_dirty_block(codeblock_t *block); +static void delete_block(codeblock_t *block); +static void delete_dirty_block(codeblock_t *block); /*Temporary list of code blocks that have recently been evicted. This allows for some historical state to be kept when a block is the target of self-modifying @@ -62,830 +62,793 @@ static void delete_dirty_block(codeblock_t *block); The size of this list is limited to DIRTY_LIST_MAX_SIZE blocks. When this is exceeded the oldest entry will be moved to the free list.*/ static uint16_t block_dirty_list_head, block_dirty_list_tail; -static int dirty_list_size = 0; +static int dirty_list_size = 0; #define DIRTY_LIST_MAX_SIZE 64 -static void block_free_list_add(codeblock_t *block) +static void +block_free_list_add(codeblock_t *block) { #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("block_free_list_add: block=%p in dirty list\n", block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_free_list_add: block=%p in dirty list\n", block); #endif - if (block_free_list) - block->next = block_free_list; - else - block->next = 0; - block_free_list = get_block_nr(block); - block->flags = CODEBLOCK_IN_FREE_LIST; + if (block_free_list) + block->next = block_free_list; + else + block->next = 0; + block_free_list = get_block_nr(block); + block->flags = CODEBLOCK_IN_FREE_LIST; } -static void block_dirty_list_add(codeblock_t *block) +static void +block_dirty_list_add(codeblock_t *block) { #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("block_dirty_list_add: block=%p already in dirty list\n", block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("block_dirty_list_add: block=%p already in dirty list\n", block); #endif - if (block_dirty_list_head != BLOCK_INVALID) - { - codeblock_t *old_head = &codeblock[block_dirty_list_head]; + if (block_dirty_list_head != BLOCK_INVALID) { + codeblock_t *old_head = &codeblock[block_dirty_list_head]; - block->next = block_dirty_list_head; - block->prev = BLOCK_INVALID; - block_dirty_list_head = old_head->prev = get_block_nr(block); - } - else - { - /*List empty*/ - block->prev = block->next = BLOCK_INVALID; - block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); - } - block->flags |= CODEBLOCK_IN_DIRTY_LIST; - dirty_list_size++; - if (dirty_list_size > DIRTY_LIST_MAX_SIZE) - { - /*Evict oldest block to the free list*/ - codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; + block->next = block_dirty_list_head; + block->prev = BLOCK_INVALID; + block_dirty_list_head = old_head->prev = get_block_nr(block); + } else { + /*List empty*/ + block->prev = block->next = BLOCK_INVALID; + block_dirty_list_head = block_dirty_list_tail = get_block_nr(block); + } + block->flags |= CODEBLOCK_IN_DIRTY_LIST; + dirty_list_size++; + if (dirty_list_size > DIRTY_LIST_MAX_SIZE) { + /*Evict oldest block to the free list*/ + codeblock_t *evict_block = &codeblock[block_dirty_list_tail]; #ifndef RELEASE_BUILD - if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) - fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); - if (!block_dirty_list_tail) - fatal("block_dirty_list_add - !block_dirty_list_tail\n"); - if (evict_block->prev == BLOCK_INVALID) - fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); + if (!(evict_block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_add: evict_block=%p %x %x not in dirty list\n", evict_block, evict_block->phys, evict_block->flags); + if (!block_dirty_list_tail) + fatal("block_dirty_list_add - !block_dirty_list_tail\n"); + if (evict_block->prev == BLOCK_INVALID) + fatal("block_dirty_list_add - evict_block->prev == BLOCK_INVALID\n"); #endif - block_dirty_list_tail = evict_block->prev; - codeblock[evict_block->prev].next = BLOCK_INVALID; - - dirty_list_size--; - evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; - delete_dirty_block(evict_block); - } -} - -static void block_dirty_list_remove(codeblock_t *block) -{ - codeblock_t *prev_block = &codeblock[block->prev]; - codeblock_t *next_block = &codeblock[block->next]; - -#ifndef RELEASE_BUILD - if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) - fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); -#endif - - /*Is block head of list*/ - if (block->prev == BLOCK_INVALID) - block_dirty_list_head = block->next; - else - prev_block->next = block->next; - - /*Is block tail of list?*/ - if (block->next == BLOCK_INVALID) - block_dirty_list_tail = block->prev; - else - next_block->prev = block->prev; + block_dirty_list_tail = evict_block->prev; + codeblock[evict_block->prev].next = BLOCK_INVALID; dirty_list_size--; + evict_block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + delete_dirty_block(evict_block); + } +} + +static void +block_dirty_list_remove(codeblock_t *block) +{ + codeblock_t *prev_block = &codeblock[block->prev]; + codeblock_t *next_block = &codeblock[block->next]; + #ifndef RELEASE_BUILD - if (dirty_list_size < 0) - fatal("remove - dirty_list_size < 0!\n"); + if (!(block->flags & CODEBLOCK_IN_DIRTY_LIST)) + fatal("block_dirty_list_remove: block=%p not in dirty list\n", block); #endif - block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; -} -int codegen_purge_purgable_list(void) -{ - if (purgable_page_list_head) - { - page_t *page = &pages[purgable_page_list_head]; + /*Is block head of list*/ + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = block->next; + else + prev_block->next = block->next; - if (page->code_present_mask & page->dirty_mask) - { - codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); + /*Is block tail of list?*/ + if (block->next == BLOCK_INVALID) + block_dirty_list_tail = block->prev; + else + next_block->prev = block->prev; - if (block_free_list) - return 1; - } - } - return 0; -} - -static codeblock_t *block_free_list_get(void) -{ - codeblock_t *block = NULL; - - while (!block_free_list) - { - /*Free list is empty, check the dirty list*/ - if (block_dirty_list_tail) - { + dirty_list_size--; #ifndef RELEASE_BUILD - if (dirty_list_size <= 0) - fatal("get - dirty_list_size <= 0!\n"); + if (dirty_list_size < 0) + fatal("remove - dirty_list_size < 0!\n"); #endif - /*Reuse oldest block*/ - block = &codeblock[block_dirty_list_tail]; - - block_dirty_list_tail = block->prev; - if (block->prev == BLOCK_INVALID) - block_dirty_list_head = BLOCK_INVALID; - else - codeblock[block->prev].next = BLOCK_INVALID; - dirty_list_size--; - block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; - delete_dirty_block(block); - block_free_list = get_block_nr(block); - break; - } - /*Free list is empty - free up a block*/ - if (!codegen_purge_purgable_list()) - codegen_delete_random_block(0); - } - - block = &codeblock[block_free_list]; - block_free_list = block->next; - block->flags &= ~CODEBLOCK_IN_FREE_LIST; - block->next = 0; - return block; + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; } -void codegen_init(void) +int +codegen_purge_purgable_list(void) { - int c; + if (purgable_page_list_head) { + page_t *page = &pages[purgable_page_list_head]; - codegen_allocator_init(); + if (page->code_present_mask & page->dirty_mask) { + codegen_check_flush(page, page->dirty_mask, purgable_page_list_head << 12); - codegen_backend_init(); - block_free_list = 0; - for (c = 0; c < BLOCK_SIZE; c++) - block_free_list_add(&codeblock[c]); - block_dirty_list_head = block_dirty_list_tail = 0; - dirty_list_size = 0; + if (block_free_list) + return 1; + } + } + return 0; +} + +static codeblock_t * +block_free_list_get(void) +{ + codeblock_t *block = NULL; + + while (!block_free_list) { + /*Free list is empty, check the dirty list*/ + if (block_dirty_list_tail) { +#ifndef RELEASE_BUILD + if (dirty_list_size <= 0) + fatal("get - dirty_list_size <= 0!\n"); +#endif + /*Reuse oldest block*/ + block = &codeblock[block_dirty_list_tail]; + + block_dirty_list_tail = block->prev; + if (block->prev == BLOCK_INVALID) + block_dirty_list_head = BLOCK_INVALID; + else + codeblock[block->prev].next = BLOCK_INVALID; + dirty_list_size--; + block->flags &= ~CODEBLOCK_IN_DIRTY_LIST; + delete_dirty_block(block); + block_free_list = get_block_nr(block); + break; + } + /*Free list is empty - free up a block*/ + if (!codegen_purge_purgable_list()) + codegen_delete_random_block(0); + } + + block = &codeblock[block_free_list]; + block_free_list = block->next; + block->flags &= ~CODEBLOCK_IN_FREE_LIST; + block->next = 0; + return block; +} + +void +codegen_init(void) +{ + int c; + + codegen_allocator_init(); + + codegen_backend_init(); + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) + block_free_list_add(&codeblock[c]); + block_dirty_list_head = block_dirty_list_tail = 0; + dirty_list_size = 0; #ifdef DEBUG_EXTRA - memset(instr_counts, 0, sizeof(instr_counts)); + memset(instr_counts, 0, sizeof(instr_counts)); #endif } -void codegen_close(void) +void +codegen_close(void) { #ifdef DEBUG_EXTRA - pclog("Instruction counts :\n"); - while (1) - { - int c; - uint32_t highest_num = 0, highest_idx = 0; + pclog("Instruction counts :\n"); + while (1) { + int c; + uint32_t highest_num = 0, highest_idx = 0; - for (c = 0; c < 256*256; c++) - { - if (instr_counts[c] > highest_num) - { - highest_num = instr_counts[c]; - highest_idx = c; - } - } - if (!highest_num) - break; - - instr_counts[highest_idx] = 0; - if (highest_idx > 256) - pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); - else - pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + for (c = 0; c < 256 * 256; c++) { + if (instr_counts[c] > highest_num) { + highest_num = instr_counts[c]; + highest_idx = c; + } } -#endif -} + if (!highest_num) + break; -void codegen_reset(void) -{ - int c; - - for (c = 1; c < BLOCK_SIZE; c++) - { - codeblock_t *block = &codeblock[c]; - - if (block->pc != BLOCK_PC_INVALID) - { - block->phys = 0; - block->phys_2 = 0; - delete_block(block); - } - } - - memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); - memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); - mem_reset_page_blocks(); - - block_free_list = 0; - for (c = 0; c < BLOCK_SIZE; c++) - { - codeblock[c].pc = BLOCK_PC_INVALID; - block_free_list_add(&codeblock[c]); - } -} - -void dump_block(void) -{ -/* codeblock_t *block = pages[0x119000 >> 12].block; - - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); - - block = block->next; - } - pclog("dump_block done\n");*/ -} - -static void add_to_block_list(codeblock_t *block) -{ - uint16_t block_prev_nr = pages[block->phys >> 12].block; - uint16_t block_nr = get_block_nr(block); - -#ifndef RELEASE_BUILD - if (!block->page_mask) - fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask,block->page_mask2); -#endif - - if (block_prev_nr) - { - block->next = block_prev_nr; - codeblock[block_prev_nr].prev = block_nr; - pages[block->phys >> 12].block = block_nr; - } + instr_counts[highest_idx] = 0; + if (highest_idx > 256) + pclog(" %02x %02x = %u\n", highest_idx >> 8, highest_idx & 0xff, highest_num); else - { - block->next = BLOCK_INVALID; - pages[block->phys >> 12].block = block_nr; - } + pclog(" %02x = %u\n", highest_idx & 0xff, highest_num); + } +#endif +} +void +codegen_reset(void) +{ + int c; + + for (c = 1; c < BLOCK_SIZE; c++) { + codeblock_t *block = &codeblock[c]; + + if (block->pc != BLOCK_PC_INVALID) { + block->phys = 0; + block->phys_2 = 0; + delete_block(block); + } + } + + memset(codeblock, 0, BLOCK_SIZE * sizeof(codeblock_t)); + memset(codeblock_hash, 0, HASH_SIZE * sizeof(uint16_t)); + mem_reset_page_blocks(); + + block_free_list = 0; + for (c = 0; c < BLOCK_SIZE; c++) { + codeblock[c].pc = BLOCK_PC_INVALID; + block_free_list_add(&codeblock[c]); + } +} + +void +dump_block(void) +{ + /* codeblock_t *block = pages[0x119000 >> 12].block; + + pclog("dump_block:\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); + if (!block->pc) + fatal("Dead PC=0\n"); + + block = block->next; + } + pclog("dump_block done\n");*/ +} + +static void +add_to_block_list(codeblock_t *block) +{ + uint16_t block_prev_nr = pages[block->phys >> 12].block; + uint16_t block_nr = get_block_nr(block); + +#ifndef RELEASE_BUILD + if (!block->page_mask) + fatal("add_to_block_list - mask = 0 %llx %llx\n", block->page_mask, block->page_mask2); +#endif + + if (block_prev_nr) { + block->next = block_prev_nr; + codeblock[block_prev_nr].prev = block_nr; + pages[block->phys >> 12].block = block_nr; + } else { + block->next = BLOCK_INVALID; + pages[block->phys >> 12].block = block_nr; + } + + if (block->next) { +#ifndef RELEASE_BUILD + if (codeblock[block->next].pc == BLOCK_PC_INVALID) + fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *) &codeblock[block->next], (void *) codeblock, block_current, block_pos); +#endif + } + + if (block->page_mask2) { + block->flags |= CODEBLOCK_HAS_PAGE2; + + block_prev_nr = pages[block->phys_2 >> 12].block_2; + + if (block_prev_nr) { + block->next_2 = block_prev_nr; + codeblock[block_prev_nr].prev_2 = block_nr; + pages[block->phys_2 >> 12].block_2 = block_nr; + } else { + block->next_2 = BLOCK_INVALID; + pages[block->phys_2 >> 12].block_2 = block_nr; + } + } +} + +static void +remove_from_block_list(codeblock_t *block, uint32_t pc) +{ + if (!block->page_mask) + return; +#ifndef RELEASE_BUILD + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("remove_from_block_list: in dirty list\n"); +#endif + if (block->prev) { + codeblock[block->prev].next = block->next; if (block->next) - { + codeblock[block->next].prev = block->prev; + } else { + pages[block->phys >> 12].block = block->next; + if (block->next) + codeblock[block->next].prev = BLOCK_INVALID; + else + mem_flush_write_page(block->phys, 0); + } + + if (!(block->flags & CODEBLOCK_HAS_PAGE2)) { #ifndef RELEASE_BUILD - if (codeblock[block->next].pc == BLOCK_PC_INVALID) - fatal("block->next->pc=BLOCK_PC_INVALID %p %p %x %x\n", (void *)&codeblock[block->next], (void *)codeblock, block_current, block_pos); + if (block->prev_2 || block->next_2) + fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); #endif - } + return; + } + block->flags &= ~CODEBLOCK_HAS_PAGE2; - if (block->page_mask2) - { - block->flags |= CODEBLOCK_HAS_PAGE2; - - block_prev_nr = pages[block->phys_2 >> 12].block_2; - - if (block_prev_nr) - { - block->next_2 = block_prev_nr; - codeblock[block_prev_nr].prev_2 = block_nr; - pages[block->phys_2 >> 12].block_2 = block_nr; - } - else - { - block->next_2 = BLOCK_INVALID; - pages[block->phys_2 >> 12].block_2 = block_nr; - } - } + if (block->prev_2) { + codeblock[block->prev_2].next_2 = block->next_2; + if (block->next_2) + codeblock[block->next_2].prev_2 = block->prev_2; + } else { + pages[block->phys_2 >> 12].block_2 = block->next_2; + if (block->next_2) + codeblock[block->next_2].prev_2 = BLOCK_INVALID; + else + mem_flush_write_page(block->phys_2, 0); + } } -static void remove_from_block_list(codeblock_t *block, uint32_t pc) +static void +invalidate_block(codeblock_t *block) { - if (!block->page_mask) - return; -#ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("remove_from_block_list: in dirty list\n"); -#endif - if (block->prev) - { - codeblock[block->prev].next = block->next; - if (block->next) - codeblock[block->next].prev = block->prev; - } - else - { - pages[block->phys >> 12].block = block->next; - if (block->next) - codeblock[block->next].prev = BLOCK_INVALID; - else - mem_flush_write_page(block->phys, 0); - } + uint32_t old_pc = block->pc; - if (!(block->flags & CODEBLOCK_HAS_PAGE2)) - { #ifndef RELEASE_BUILD - if (block->prev_2 || block->next_2) - fatal("Invalid block_2 %x %p %08x\n", block->flags, block, block->phys); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + fatal("invalidate_block: already in dirty list\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Invalidating deleted block\n"); #endif - return; - } - block->flags &= ~CODEBLOCK_HAS_PAGE2; - - if (block->prev_2) - { - codeblock[block->prev_2].next_2 = block->next_2; - if (block->next_2) - codeblock[block->next_2].prev_2 = block->prev_2; - } - else - { - pages[block->phys_2 >> 12].block_2 = block->next_2; - if (block->next_2) - codeblock[block->next_2].prev_2 = BLOCK_INVALID; - else - mem_flush_write_page(block->phys_2, 0); - } + remove_from_block_list(block, old_pc); + block_dirty_list_add(block); + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; } -static void invalidate_block(codeblock_t *block) +static void +delete_block(codeblock_t *block) { - uint32_t old_pc = block->pc; + uint32_t old_pc = block->pc; + + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; #ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - fatal("invalidate_block: already in dirty list\n"); - if (block->pc == BLOCK_PC_INVALID) - fatal("Invalidating deleted block\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); #endif + block->pc = BLOCK_PC_INVALID; + + codeblock_tree_delete(block); + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else remove_from_block_list(block, old_pc); - block_dirty_list_add(block); - if (block->head_mem_block) - codegen_allocator_free(block->head_mem_block); - block->head_mem_block = NULL; + if (block->head_mem_block) + codegen_allocator_free(block->head_mem_block); + block->head_mem_block = NULL; + block_free_list_add(block); } -static void delete_block(codeblock_t *block) +static void +delete_dirty_block(codeblock_t *block) { - uint32_t old_pc = block->pc; - - if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) - codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; + if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) + codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; #ifndef RELEASE_BUILD - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); + if (block->pc == BLOCK_PC_INVALID) + fatal("Deleting deleted block\n"); #endif - block->pc = BLOCK_PC_INVALID; + block->pc = BLOCK_PC_INVALID; - codeblock_tree_delete(block); - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block_dirty_list_remove(block); - else - remove_from_block_list(block, old_pc); - if (block->head_mem_block) - codegen_allocator_free(block->head_mem_block); - block->head_mem_block = NULL; - block_free_list_add(block); + codeblock_tree_delete(block); + block_free_list_add(block); } -static void delete_dirty_block(codeblock_t *block) +void +codegen_delete_block(codeblock_t *block) { - if (block == &codeblock[codeblock_hash[HASH(block->phys)]]) - codeblock_hash[HASH(block->phys)] = BLOCK_INVALID; - -#ifndef RELEASE_BUILD - if (block->pc == BLOCK_PC_INVALID) - fatal("Deleting deleted block\n"); -#endif - block->pc = BLOCK_PC_INVALID; - - codeblock_tree_delete(block); - block_free_list_add(block); + if (block->pc != BLOCK_PC_INVALID) + delete_block(block); } -void codegen_delete_block(codeblock_t *block) +void +codegen_delete_random_block(int required_mem_block) { - if (block->pc != BLOCK_PC_INVALID) + int block_nr = rand() & BLOCK_MASK; + + while (1) { + if (block_nr && block_nr != block_current) { + codeblock_t *block = &codeblock[block_nr]; + + if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) { delete_block(block); + return; + } + } + block_nr = (block_nr + 1) & BLOCK_MASK; + } } -void codegen_delete_random_block(int required_mem_block) +void +codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) { - int block_nr = rand() & BLOCK_MASK; + uint16_t block_nr = page->block; + int remove_from_evict_list = 0; + int c; - while (1) - { - if (block_nr && block_nr != block_current) - { - codeblock_t *block = &codeblock[block_nr]; + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next; - if (block->pc != BLOCK_PC_INVALID && (!required_mem_block || block->head_mem_block)) - { - delete_block(block); - return; - } - } - block_nr = (block_nr + 1) & BLOCK_MASK; + if (*block->dirty_mask & block->page_mask) { + invalidate_block(block); } +#ifndef RELEASE_BUILD + if (block_nr == next_block) + fatal("Broken 1\n"); +#endif + block_nr = next_block; + } + + block_nr = page->block_2; + + while (block_nr) { + codeblock_t *block = &codeblock[block_nr]; + uint16_t next_block = block->next_2; + + if (*block->dirty_mask2 & block->page_mask2) { + invalidate_block(block); + } +#ifndef RELEASE_BUILD + if (block_nr == next_block) + fatal("Broken 2\n"); +#endif + block_nr = next_block; + } + + if (page->code_present_mask & page->dirty_mask) + remove_from_evict_list = 1; + page->code_present_mask &= ~page->dirty_mask; + page->dirty_mask = 0; + + for (c = 0; c < 64; c++) { + if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) + remove_from_evict_list = 0; + page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; + page->byte_dirty_mask[c] = 0; + } + if (remove_from_evict_list) + page_remove_from_evict_list(page); } -void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) +void +codegen_block_init(uint32_t phys_addr) { - uint16_t block_nr = page->block; - int remove_from_evict_list = 0; - int c; + codeblock_t *block; + page_t *page = &pages[phys_addr >> 12]; - while (block_nr) - { - codeblock_t *block = &codeblock[block_nr]; - uint16_t next_block = block->next; - - if (*block->dirty_mask & block->page_mask) - { - invalidate_block(block); - } + if (!page->block) + mem_flush_write_page(phys_addr, cs + cpu_state.pc); + block = block_free_list_get(); #ifndef RELEASE_BUILD - if (block_nr == next_block) - fatal("Broken 1\n"); + if (!block) + fatal("codegen_block_init: block_free_list_get() returned NULL\n"); #endif - block_nr = next_block; - } + block_current = get_block_nr(block); - block_nr = page->block_2; + block_num = HASH(phys_addr); + codeblock_hash[block_num] = block_current; - while (block_nr) - { - codeblock_t *block = &codeblock[block_nr]; - uint16_t next_block = block->next_2; + block->ins = 0; + block->pc = cs + cpu_state.pc; + block->_cs = cs; + block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask; + block->dirty_mask2 = NULL; + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; + block->page_mask = block->page_mask2 = 0; + block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; - if (*block->dirty_mask2 & block->page_mask2) - { - invalidate_block(block); - } -#ifndef RELEASE_BUILD - if (block_nr == next_block) - fatal("Broken 2\n"); -#endif - block_nr = next_block; - } - - if (page->code_present_mask & page->dirty_mask) - remove_from_evict_list = 1; - page->code_present_mask &= ~page->dirty_mask; - page->dirty_mask = 0; - - for (c = 0; c < 64; c++) - { - if (page->byte_code_present_mask[c] & page->byte_dirty_mask[c]) - remove_from_evict_list = 0; - page->byte_code_present_mask[c] &= ~page->byte_dirty_mask[c]; - page->byte_dirty_mask[c] = 0; - } - if (remove_from_evict_list) - page_remove_from_evict_list(page); -} - -void codegen_block_init(uint32_t phys_addr) -{ - codeblock_t *block; - page_t *page = &pages[phys_addr >> 12]; - - if (!page->block) - mem_flush_write_page(phys_addr, cs+cpu_state.pc); - block = block_free_list_get(); -#ifndef RELEASE_BUILD - if (!block) - fatal("codegen_block_init: block_free_list_get() returned NULL\n"); -#endif - block_current = get_block_nr(block); - - block_num = HASH(phys_addr); - codeblock_hash[block_num] = block_current; - - block->ins = 0; - block->pc = cs + cpu_state.pc; - block->_cs = cs; - block->phys = phys_addr; - block->dirty_mask = &page->dirty_mask; - block->dirty_mask2 = NULL; - block->next = block->prev = BLOCK_INVALID; - block->next_2 = block->prev_2 = BLOCK_INVALID; - block->page_mask = block->page_mask2 = 0; - block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; - - recomp_page = block->phys & ~0xfff; - codeblock_tree_add(block); + recomp_page = block->phys & ~0xfff; + codeblock_tree_add(block); } static ir_data_t *ir_data; -ir_data_t *codegen_get_ir_data(void) +ir_data_t * +codegen_get_ir_data(void) { - return ir_data; + return ir_data; } -void codegen_block_start_recompile(codeblock_t *block) +void +codegen_block_start_recompile(codeblock_t *block) { - page_t *page = &pages[block->phys >> 12]; + page_t *page = &pages[block->phys >> 12]; - if (!page->block) - mem_flush_write_page(block->phys, cs+cpu_state.pc); + if (!page->block) + mem_flush_write_page(block->phys, cs + cpu_state.pc); - block_num = HASH(block->phys); - block_current = get_block_nr(block);//block->pnt; + block_num = HASH(block->phys); + block_current = get_block_nr(block); // block->pnt; #ifndef RELEASE_BUILD - if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) - fatal("Recompile to used block!\n"); + if (block->pc != cs + cpu_state.pc || (block->flags & CODEBLOCK_WAS_RECOMPILED)) + fatal("Recompile to used block!\n"); #endif - block->head_mem_block = codegen_allocator_allocate(NULL, block_current); - block->data = codeblock_allocator_get_ptr(block->head_mem_block); + block->head_mem_block = codegen_allocator_allocate(NULL, block_current); + block->data = codeblock_allocator_get_ptr(block->head_mem_block); - block->status = cpu_cur_status; + block->status = cpu_cur_status; - block->page_mask = block->page_mask2 = 0; - block->ins = 0; + block->page_mask = block->page_mask2 = 0; + block->ins = 0; - cpu_block_end = 0; + cpu_block_end = 0; - last_op32 = -1; - last_ea_seg = NULL; - last_ssegs = -1; + last_op32 = -1; + last_ea_seg = NULL; + last_ssegs = -1; - codegen_block_cycles = 0; - codegen_timing_block_start(); + codegen_block_cycles = 0; + codegen_timing_block_start(); - codegen_block_ins = 0; - codegen_block_full_ins = 0; + codegen_block_ins = 0; + codegen_block_full_ins = 0; - recomp_page = block->phys & ~0xfff; + recomp_page = block->phys & ~0xfff; - codegen_flags_changed = 0; - codegen_fpu_entered = 0; - codegen_mmx_entered = 0; + codegen_flags_changed = 0; + codegen_fpu_entered = 0; + codegen_mmx_entered = 0; - codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = - codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; - cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; + cpu_state.seg_ds.checked = cpu_state.seg_es.checked = cpu_state.seg_fs.checked = cpu_state.seg_gs.checked = (cr0 & 1) ? 0 : 1; - block->TOP = cpu_state.TOP & 7; - block->flags |= CODEBLOCK_WAS_RECOMPILED; + block->TOP = cpu_state.TOP & 7; + block->flags |= CODEBLOCK_WAS_RECOMPILED; - codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); - codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); + codegen_flat_ds = !(cpu_cur_status & CPU_STATUS_NOTFLATDS); + codegen_flat_ss = !(cpu_cur_status & CPU_STATUS_NOTFLATSS); - if (block->flags & CODEBLOCK_BYTE_MASK) - { - block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; - block->dirty_mask2 = NULL; - } + if (block->flags & CODEBLOCK_BYTE_MASK) { + block->dirty_mask = &page->byte_dirty_mask[(block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK]; + block->dirty_mask2 = NULL; + } - ir_data = codegen_ir_init(); - ir_data->block = block; - codegen_reg_reset(); - codegen_accumulate_reset(); - codegen_generate_reset(); + ir_data = codegen_ir_init(); + ir_data->block = block; + codegen_reg_reset(); + codegen_accumulate_reset(); + codegen_generate_reset(); } - -void codegen_block_remove(void) +void +codegen_block_remove(void) { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; - delete_block(block); + delete_block(block); - recomp_page = -1; + recomp_page = -1; } -void codegen_block_generate_end_mask_recompile(void) +void +codegen_block_generate_end_mask_recompile(void) { - codeblock_t *block = &codeblock[block_current]; - page_t *p; + codeblock_t *block = &codeblock[block_current]; + page_t *p; - p = &pages[block->phys >> 12]; - if (block->flags & CODEBLOCK_BYTE_MASK) - { - int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + p = &pages[block->phys >> 12]; + if (block->flags & CODEBLOCK_BYTE_MASK) { + int offset = (block->phys >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - p->byte_code_present_mask[offset] |= block->page_mask; - } - else - p->code_present_mask |= block->page_mask; - - if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - - block->phys_2 = -1; - block->next_2 = block->prev_2 = BLOCK_INVALID; - if (block->page_mask2) - { - block->phys_2 = get_phys_noabrt(codegen_endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; - - if (block->flags & CODEBLOCK_BYTE_MASK) - { - int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - - page_2->byte_code_present_mask[offset] |= block->page_mask2; - block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; - } - else - { - page_2->code_present_mask |= block->page_mask2; - block->dirty_mask2 = &page_2->dirty_mask; - } - if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) - page_add_to_evict_list(page_2); - - if (!pages[block->phys_2 >> 12].block_2) - mem_flush_write_page(block->phys_2, codegen_endpc); - -#ifndef RELEASE_BUILD - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); - } -#endif - } - else - { - /*Second page not present. page_mask2 is most likely set only because - the recompiler didn't know how long the last instruction was, so - clear it*/ - block->page_mask2 = 0; - } - } - - recomp_page = -1; -} - -void codegen_block_generate_end_mask_mark(void) -{ - codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc; - uint32_t end_pc; - page_t *p; - -#ifndef RELEASE_BUILD - if (block->flags & CODEBLOCK_BYTE_MASK) - fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); -#endif - - block->page_mask = 0; - start_pc = (block->pc & 0xfff) & ~63; - if ((block->pc ^ codegen_endpc) & ~0xfff) - end_pc = 0xfff & ~63; - else - end_pc = (codegen_endpc & 0xfff) & ~63; - if (end_pc < start_pc) - end_pc = 0xfff; - start_pc >>= PAGE_MASK_SHIFT; - end_pc >>= PAGE_MASK_SHIFT; - - for (; start_pc <= end_pc; start_pc++) - { - block->page_mask |= ((uint64_t)1 << start_pc); - } - - p = &pages[block->phys >> 12]; + p->byte_code_present_mask[offset] |= block->page_mask; + } else p->code_present_mask |= block->page_mask; - if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) - page_add_to_evict_list(p); - block->phys_2 = -1; - block->page_mask2 = 0; - block->next_2 = block->prev_2 = BLOCK_INVALID; - if ((block->pc ^ codegen_endpc) & ~0xfff) - { - block->phys_2 = get_phys_noabrt(codegen_endpc); - if (block->phys_2 != -1) - { - page_t *page_2 = &pages[block->phys_2 >> 12]; + if ((*(block->dirty_mask) & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); - start_pc = 0; - end_pc = (codegen_endpc & 0xfff) >> PAGE_MASK_SHIFT; - for (; start_pc <= end_pc; start_pc++) - block->page_mask2 |= ((uint64_t)1 << start_pc); + block->phys_2 = -1; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if (block->page_mask2) { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; - page_2->code_present_mask |= block->page_mask2; - if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) - page_add_to_evict_list(page_2); + if (block->flags & CODEBLOCK_BYTE_MASK) { + int offset = (block->phys_2 >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - if (!pages[block->phys_2 >> 12].block_2) - mem_flush_write_page(block->phys_2, codegen_endpc); + page_2->byte_code_present_mask[offset] |= block->page_mask2; + block->dirty_mask2 = &page_2->byte_dirty_mask[offset]; + } else { + page_2->code_present_mask |= block->page_mask2; + block->dirty_mask2 = &page_2->dirty_mask; + } + if (((*block->dirty_mask2) & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); + + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); #ifndef RELEASE_BUILD - if (!block->page_mask2) - fatal("!page_mask2\n"); - if (block->next_2) - { - if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) - fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *)&codeblock[block->next_2]); - } + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *) &codeblock[block->next_2]); + } #endif - block->dirty_mask2 = &page_2->dirty_mask; - } - else - { - /*Second page not present. page_mask2 is most likely set only because - the recompiler didn't know how long the last instruction was, so - clear it*/ - block->page_mask2 = 0; - } + } else { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; } + } - recomp_page = -1; + recomp_page = -1; } -void codegen_block_end(void) +void +codegen_block_generate_end_mask_mark(void) { - codeblock_t *block = &codeblock[block_current]; + codeblock_t *block = &codeblock[block_current]; + uint32_t start_pc; + uint32_t end_pc; + page_t *p; - codegen_block_generate_end_mask_mark(); - add_to_block_list(block); -} +#ifndef RELEASE_BUILD + if (block->flags & CODEBLOCK_BYTE_MASK) + fatal("codegen_block_generate_end_mask2() - BYTE_MASK\n"); +#endif -void codegen_block_end_recompile(codeblock_t *block) -{ - codegen_timing_block_end(); - codegen_accumulate(ir_data, ACCREG_cycles, -codegen_block_cycles); + block->page_mask = 0; + start_pc = (block->pc & 0xfff) & ~63; + if ((block->pc ^ codegen_endpc) & ~0xfff) + end_pc = 0xfff & ~63; + else + end_pc = (codegen_endpc & 0xfff) & ~63; + if (end_pc < start_pc) + end_pc = 0xfff; + start_pc >>= PAGE_MASK_SHIFT; + end_pc >>= PAGE_MASK_SHIFT; - if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block_dirty_list_remove(block); - else - remove_from_block_list(block, block->pc); - block->next = block->prev = BLOCK_INVALID; - block->next_2 = block->prev_2 = BLOCK_INVALID; - codegen_block_generate_end_mask_recompile(); - add_to_block_list(block); + for (; start_pc <= end_pc; start_pc++) { + block->page_mask |= ((uint64_t) 1 << start_pc); + } - if (!(block->flags & CODEBLOCK_HAS_FPU)) - block->flags &= ~CODEBLOCK_STATIC_TOP; + p = &pages[block->phys >> 12]; + p->code_present_mask |= block->page_mask; + if ((p->dirty_mask & block->page_mask) && !page_in_evict_list(p)) + page_add_to_evict_list(p); - codegen_accumulate_flush(ir_data); - codegen_ir_compile(ir_data, block); -} + block->phys_2 = -1; + block->page_mask2 = 0; + block->next_2 = block->prev_2 = BLOCK_INVALID; + if ((block->pc ^ codegen_endpc) & ~0xfff) { + block->phys_2 = get_phys_noabrt(codegen_endpc); + if (block->phys_2 != -1) { + page_t *page_2 = &pages[block->phys_2 >> 12]; -void codegen_flush(void) -{ - return; -} + start_pc = 0; + end_pc = (codegen_endpc & 0xfff) >> PAGE_MASK_SHIFT; + for (; start_pc <= end_pc; start_pc++) + block->page_mask2 |= ((uint64_t) 1 << start_pc); -void codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len) -{ - if (len) - { - uint32_t end_pc = start_pc + (len-1); + page_2->code_present_mask |= block->page_mask2; + if ((page_2->dirty_mask & block->page_mask2) && !page_in_evict_list(page_2)) + page_add_to_evict_list(page_2); - if (block->flags & CODEBLOCK_BYTE_MASK) - { - uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; - uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; + if (!pages[block->phys_2 >> 12].block_2) + mem_flush_write_page(block->phys_2, codegen_endpc); - if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ - { - for (; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask2 |= ((uint64_t)1 << start_pc_masked); - } - else if (((start_pc + (len-1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ - { - for (; start_pc_masked <= 63; start_pc_masked++) - block->page_mask |= ((uint64_t)1 << start_pc_masked); - for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask2 |= ((uint64_t)1 << start_pc_masked); - } - else /*First page only*/ - { - for (; start_pc_masked <= end_pc_masked; start_pc_masked++) - block->page_mask |= ((uint64_t)1 << start_pc_masked); - } - } - else - { - uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; - uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; - start_pc_shifted &= PAGE_MASK_MASK; - end_pc_shifted &= PAGE_MASK_MASK; - - if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ - { - for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); - } - else if (((start_pc + (len-1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ - { - for (; start_pc_shifted <= 63; start_pc_shifted++) - block->page_mask |= ((uint64_t)1 << start_pc_shifted); - for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask2 |= ((uint64_t)1 << start_pc_shifted); - } - else /*First page only*/ - { - for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) - block->page_mask |= ((uint64_t)1 << start_pc_shifted); - } - } +#ifndef RELEASE_BUILD + if (!block->page_mask2) + fatal("!page_mask2\n"); + if (block->next_2) { + if (codeblock[block->next_2].pc == BLOCK_PC_INVALID) + fatal("block->next_2->pc=BLOCK_PC_INVALID %p\n", (void *) &codeblock[block->next_2]); + } +#endif + block->dirty_mask2 = &page_2->dirty_mask; + } else { + /*Second page not present. page_mask2 is most likely set only because + the recompiler didn't know how long the last instruction was, so + clear it*/ + block->page_mask2 = 0; } + } + + recomp_page = -1; +} + +void +codegen_block_end(void) +{ + codeblock_t *block = &codeblock[block_current]; + + codegen_block_generate_end_mask_mark(); + add_to_block_list(block); +} + +void +codegen_block_end_recompile(codeblock_t *block) +{ + codegen_timing_block_end(); + codegen_accumulate(ir_data, ACCREG_cycles, -codegen_block_cycles); + + if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block_dirty_list_remove(block); + else + remove_from_block_list(block, block->pc); + block->next = block->prev = BLOCK_INVALID; + block->next_2 = block->prev_2 = BLOCK_INVALID; + codegen_block_generate_end_mask_recompile(); + add_to_block_list(block); + + if (!(block->flags & CODEBLOCK_HAS_FPU)) + block->flags &= ~CODEBLOCK_STATIC_TOP; + + codegen_accumulate_flush(ir_data); + codegen_ir_compile(ir_data, block); +} + +void +codegen_flush(void) +{ + return; +} + +void +codegen_mark_code_present_multibyte(codeblock_t *block, uint32_t start_pc, int len) +{ + if (len) { + uint32_t end_pc = start_pc + (len - 1); + + if (block->flags & CODEBLOCK_BYTE_MASK) { + uint32_t start_pc_masked = start_pc & PAGE_MASK_MASK; + uint32_t end_pc_masked = end_pc & PAGE_MASK_MASK; + + if ((start_pc ^ block->pc) & ~0x3f) /*Starts in second page*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_masked); + } else if (((start_pc + (len - 1)) ^ block->pc) & ~0x3f) /*Crosses both pages*/ + { + for (; start_pc_masked <= 63; start_pc_masked++) + block->page_mask |= ((uint64_t) 1 << start_pc_masked); + for (start_pc_masked = 0; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_masked); + } else /*First page only*/ + { + for (; start_pc_masked <= end_pc_masked; start_pc_masked++) + block->page_mask |= ((uint64_t) 1 << start_pc_masked); + } + } else { + uint32_t start_pc_shifted = start_pc >> PAGE_MASK_SHIFT; + uint32_t end_pc_shifted = end_pc >> PAGE_MASK_SHIFT; + start_pc_shifted &= PAGE_MASK_MASK; + end_pc_shifted &= PAGE_MASK_MASK; + + if ((start_pc ^ block->pc) & ~0xfff) /*Starts in second page*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_shifted); + } else if (((start_pc + (len - 1)) ^ block->pc) & ~0xfff) /*Crosses both pages*/ + { + for (; start_pc_shifted <= 63; start_pc_shifted++) + block->page_mask |= ((uint64_t) 1 << start_pc_shifted); + for (start_pc_shifted = 0; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask2 |= ((uint64_t) 1 << start_pc_shifted); + } else /*First page only*/ + { + for (; start_pc_shifted <= end_pc_shifted; start_pc_shifted++) + block->page_mask |= ((uint64_t) 1 << start_pc_shifted); + } + } + } } diff --git a/src/codegen_new/codegen_ir.c b/src/codegen_new/codegen_ir.c index 09c593f08..bc38a3666 100644 --- a/src/codegen_new/codegen_ir.c +++ b/src/codegen_new/codegen_ir.c @@ -9,208 +9,186 @@ #include "codegen_ir.h" #include "codegen_reg.h" -extern int has_ea; +extern int has_ea; static ir_data_t ir_block; static int codegen_unroll_start, codegen_unroll_count; static int codegen_unroll_first_instruction; -ir_data_t *codegen_ir_init(void) +ir_data_t * +codegen_ir_init(void) { - ir_block.wr_pos = 0; + ir_block.wr_pos = 0; - codegen_unroll_count = 0; + codegen_unroll_count = 0; - return &ir_block; + return &ir_block; } -void codegen_ir_set_unroll(int count, int start, int first_instruction) +void +codegen_ir_set_unroll(int count, int start, int first_instruction) { - codegen_unroll_count = count; - codegen_unroll_start = start; - codegen_unroll_first_instruction = first_instruction; + codegen_unroll_count = count; + codegen_unroll_start = start; + codegen_unroll_first_instruction = first_instruction; } -static void duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) +static void +duplicate_uop(ir_data_t *ir, uop_t *uop, int offset) { - uop_t *new_uop = uop_alloc(ir, uop->type); + uop_t *new_uop = uop_alloc(ir, uop->type); - if (!ir_reg_is_invalid(uop->src_reg_a)) - new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); - if (!ir_reg_is_invalid(uop->src_reg_b)) - new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); - if (!ir_reg_is_invalid(uop->src_reg_c)) - new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); - if (!ir_reg_is_invalid(uop->dest_reg_a)) - new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos-1); + if (!ir_reg_is_invalid(uop->src_reg_a)) + new_uop->src_reg_a = codegen_reg_read(uop->src_reg_a.reg); + if (!ir_reg_is_invalid(uop->src_reg_b)) + new_uop->src_reg_b = codegen_reg_read(uop->src_reg_b.reg); + if (!ir_reg_is_invalid(uop->src_reg_c)) + new_uop->src_reg_c = codegen_reg_read(uop->src_reg_c.reg); + if (!ir_reg_is_invalid(uop->dest_reg_a)) + new_uop->dest_reg_a = codegen_reg_write(uop->dest_reg_a.reg, ir->wr_pos - 1); - new_uop->type = uop->type; - new_uop->imm_data = uop->imm_data; - new_uop->p = uop->p; - new_uop->pc = uop->pc; + new_uop->type = uop->type; + new_uop->imm_data = uop->imm_data; + new_uop->p = uop->p; + new_uop->pc = uop->pc; - if (uop->jump_dest_uop != -1) - { - new_uop->jump_dest_uop = uop->jump_dest_uop + offset; + if (uop->jump_dest_uop != -1) { + new_uop->jump_dest_uop = uop->jump_dest_uop + offset; + } +} + +void +codegen_ir_compile(ir_data_t *ir, codeblock_t *block) +{ + int jump_target_at_end = -1; + int c; + + if (codegen_unroll_count) { + int unroll_count; + int unroll_end; + + codegen_set_loop_start(ir, codegen_unroll_first_instruction); + unroll_end = ir->wr_pos; + + for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) { + int offset = ir->wr_pos - codegen_unroll_start; + // pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count); + for (c = codegen_unroll_start; c < unroll_end; c++) { + // pclog(" Duplicate uop %i\n", c); + duplicate_uop(ir, &ir->uops[c], offset); + } } -} + } -void codegen_ir_compile(ir_data_t *ir, codeblock_t *block) -{ - int jump_target_at_end = -1; - int c; + codegen_reg_mark_as_required(); + codegen_reg_process_dead_list(ir); + block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); + block_pos = 0; + codegen_backend_prologue(block); - if (codegen_unroll_count) - { - int unroll_count; - int unroll_end; + for (c = 0; c < ir->wr_pos; c++) { + uop_t *uop = &ir->uops[c]; - codegen_set_loop_start(ir, codegen_unroll_first_instruction); - unroll_end = ir->wr_pos; + // pclog("uOP %i : %08x\n", c, uop->type); - for (unroll_count = 1; unroll_count < codegen_unroll_count; unroll_count++) - { - int offset = ir->wr_pos - codegen_unroll_start; -// pclog("Unroll from %i to %i, offset %i - iteration %i\n", codegen_unroll_start, ir->wr_pos, offset, unroll_count); - for (c = codegen_unroll_start; c < unroll_end; c++) - { -// pclog(" Duplicate uop %i\n", c); - duplicate_uop(ir, &ir->uops[c], offset); - } - } + if (uop->type & UOP_TYPE_BARRIER) + codegen_reg_flush_invalidate(ir, block); + + if (uop->type & UOP_TYPE_JUMP_DEST) { + uop_t *uop_dest = uop; + + while (uop_dest->jump_list_next != -1) { + uop_dest = &ir->uops[uop_dest->jump_list_next]; + codegen_set_jump_dest(block, uop_dest->p); + } } - codegen_reg_mark_as_required(); - codegen_reg_process_dead_list(ir); - block_write_data = codeblock_allocator_get_ptr(block->head_mem_block); - block_pos = 0; - codegen_backend_prologue(block); - - for (c = 0; c < ir->wr_pos; c++) - { - uop_t *uop = &ir->uops[c]; - -// pclog("uOP %i : %08x\n", c, uop->type); - - if (uop->type & UOP_TYPE_BARRIER) - codegen_reg_flush_invalidate(ir, block); - - if (uop->type & UOP_TYPE_JUMP_DEST) - { - uop_t *uop_dest = uop; - - while (uop_dest->jump_list_next != -1) - { - uop_dest = &ir->uops[uop_dest->jump_list_next]; - codegen_set_jump_dest(block, uop_dest->p); - } - } - - if ((uop->type & UOP_MASK) == UOP_INVALID) - continue; + if ((uop->type & UOP_MASK) == UOP_INVALID) + continue; #ifdef CODEGEN_BACKEND_HAS_MOV_IMM - if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) - { - /*Special case for UOP_MOV_IMM - if destination not already in host register - and won't be used again then just store directly to memory*/ - codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); - } - else + if ((uop->type & UOP_MASK) == (UOP_MOV_IMM & UOP_MASK) && reg_is_native_size(uop->dest_reg_a) && !codegen_reg_is_loaded(uop->dest_reg_a) && reg_version[IREG_GET_REG(uop->dest_reg_a.reg)][uop->dest_reg_a.version].refcount <= 0) { + /*Special case for UOP_MOV_IMM - if destination not already in host register + and won't be used again then just store directly to memory*/ + codegen_reg_write_imm(block, uop->dest_reg_a, uop->imm_data); + } else #endif - if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && - reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) - { - /*Special case for UOP_MOV - if source register won't be used again then - just rename it to dest register instead of moving*/ - codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); + if ((uop->type & UOP_MASK) == (UOP_MOV & UOP_MASK) && reg_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version].refcount <= 1 && reg_is_native_size(uop->src_reg_a) && reg_is_native_size(uop->dest_reg_a)) { + /*Special case for UOP_MOV - if source register won't be used again then + just rename it to dest register instead of moving*/ + codegen_reg_alloc_register(invalid_ir_reg, uop->src_reg_a, invalid_ir_reg, invalid_ir_reg); + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); + codegen_reg_rename(block, uop->src_reg_a, uop->dest_reg_a); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); + } else { + if (uop->type & UOP_TYPE_PARAMS_REGS) { + codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); + if (uop->src_reg_a.reg != IREG_INVALID) { + uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); } - else - { - if (uop->type & UOP_TYPE_PARAMS_REGS) - { - codegen_reg_alloc_register(uop->dest_reg_a, uop->src_reg_a, uop->src_reg_b, uop->src_reg_c); - if (uop->src_reg_a.reg != IREG_INVALID) - { - uop->src_reg_a_real = codegen_reg_alloc_read_reg(block, uop->src_reg_a, NULL); - } - if (uop->src_reg_b.reg != IREG_INVALID) - { - uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); - } - if (uop->src_reg_c.reg != IREG_INVALID) - { - uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); - } - } + if (uop->src_reg_b.reg != IREG_INVALID) { + uop->src_reg_b_real = codegen_reg_alloc_read_reg(block, uop->src_reg_b, NULL); + } + if (uop->src_reg_c.reg != IREG_INVALID) { + uop->src_reg_c_real = codegen_reg_alloc_read_reg(block, uop->src_reg_c, NULL); + } + } - if (uop->type & UOP_TYPE_ORDER_BARRIER) - codegen_reg_flush(ir, block); + if (uop->type & UOP_TYPE_ORDER_BARRIER) + codegen_reg_flush(ir, block); - if (uop->type & UOP_TYPE_PARAMS_REGS) - { - if (uop->dest_reg_a.reg != IREG_INVALID) - { - uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); - } - } + if (uop->type & UOP_TYPE_PARAMS_REGS) { + if (uop->dest_reg_a.reg != IREG_INVALID) { + uop->dest_reg_a_real = codegen_reg_alloc_write_reg(block, uop->dest_reg_a); + } + } #ifndef RELEASE_BUILD - if (!uop_handlers[uop->type & UOP_MASK]) - fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); + if (!uop_handlers[uop->type & UOP_MASK]) + fatal("!uop_handlers[uop->type & UOP_MASK] %08x\n", uop->type); #endif - uop_handlers[uop->type & UOP_MASK](block, uop); - } - - if (uop->type & UOP_TYPE_JUMP) - { - if (uop->jump_dest_uop == ir->wr_pos) - { - if (jump_target_at_end == -1) - jump_target_at_end = c; - else - { - uop_t *uop_dest = &ir->uops[jump_target_at_end]; - - while (uop_dest->jump_list_next != -1) - uop_dest = &ir->uops[uop_dest->jump_list_next]; - - uop_dest->jump_list_next = c; - } - } - else - { - uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; - - while (uop_dest->jump_list_next != -1) - uop_dest = &ir->uops[uop_dest->jump_list_next]; - - uop_dest->jump_list_next = c; - ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; - } - } + uop_handlers[uop->type & UOP_MASK](block, uop); } - codegen_reg_flush_invalidate(ir, block); + if (uop->type & UOP_TYPE_JUMP) { + if (uop->jump_dest_uop == ir->wr_pos) { + if (jump_target_at_end == -1) + jump_target_at_end = c; + else { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; - if (jump_target_at_end != -1) - { - uop_t *uop_dest = &ir->uops[jump_target_at_end]; - - while (1) - { - codegen_set_jump_dest(block, uop_dest->p); - if (uop_dest->jump_list_next == -1) - break; + while (uop_dest->jump_list_next != -1) uop_dest = &ir->uops[uop_dest->jump_list_next]; - } - } - codegen_backend_epilogue(block); - block_write_data = NULL; -// if (has_ea) -// fatal("IR compilation complete\n"); + uop_dest->jump_list_next = c; + } + } else { + uop_t *uop_dest = &ir->uops[uop->jump_dest_uop]; + + while (uop_dest->jump_list_next != -1) + uop_dest = &ir->uops[uop_dest->jump_list_next]; + + uop_dest->jump_list_next = c; + ir->uops[uop->jump_dest_uop].type |= UOP_TYPE_JUMP_DEST; + } + } + } + + codegen_reg_flush_invalidate(ir, block); + + if (jump_target_at_end != -1) { + uop_t *uop_dest = &ir->uops[jump_target_at_end]; + + while (1) { + codegen_set_jump_dest(block, uop_dest->p); + if (uop_dest->jump_list_next == -1) + break; + uop_dest = &ir->uops[uop_dest->jump_list_next]; + } + } + + codegen_backend_epilogue(block); + block_write_data = NULL; + // if (has_ea) + // fatal("IR compilation complete\n"); } diff --git a/src/codegen_new/codegen_ir_defs.h b/src/codegen_new/codegen_ir_defs.h index 30bf44d98..26a1c3cb4 100644 --- a/src/codegen_new/codegen_ir_defs.h +++ b/src/codegen_new/codegen_ir_defs.h @@ -18,761 +18,793 @@ #define UOP_TYPE_ORDER_BARRIER (1 << 27) /*uOP uses source and dest registers*/ -#define UOP_TYPE_PARAMS_REGS (1 << 28) +#define UOP_TYPE_PARAMS_REGS (1 << 28) /*uOP uses pointer*/ #define UOP_TYPE_PARAMS_POINTER (1 << 29) /*uOP uses immediate data*/ -#define UOP_TYPE_PARAMS_IMM (1 << 30) +#define UOP_TYPE_PARAMS_IMM (1 << 30) /*uOP is a jump, with the destination uOP in uop->jump_dest_uop. The compiler must set jump_dest in the destination uOP to the address of the branch offset to be written when known.*/ -#define UOP_TYPE_JUMP (1 << 26) +#define UOP_TYPE_JUMP (1 << 26) /*uOP is the destination of a jump, and must set the destination offset of the jump at compile time.*/ #define UOP_TYPE_JUMP_DEST (1 << 25) - -#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) -#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) -#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) -#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) -#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) -#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) -#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_0 (UOP_TYPE_PARAMS_REGS | 0x00) +#define UOP_LOAD_FUNC_ARG_1 (UOP_TYPE_PARAMS_REGS | 0x01) +#define UOP_LOAD_FUNC_ARG_2 (UOP_TYPE_PARAMS_REGS | 0x02) +#define UOP_LOAD_FUNC_ARG_3 (UOP_TYPE_PARAMS_REGS | 0x03) +#define UOP_LOAD_FUNC_ARG_0_IMM (UOP_TYPE_PARAMS_IMM | 0x08 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_1_IMM (UOP_TYPE_PARAMS_IMM | 0x09 | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_2_IMM (UOP_TYPE_PARAMS_IMM | 0x0a | UOP_TYPE_BARRIER) +#define UOP_LOAD_FUNC_ARG_3_IMM (UOP_TYPE_PARAMS_IMM | 0x0b | UOP_TYPE_BARRIER) +#define UOP_CALL_FUNC (UOP_TYPE_PARAMS_POINTER | 0x10 | UOP_TYPE_BARRIER) /*UOP_CALL_INSTRUCTION_FUNC - call instruction handler at p, check return value and exit block if non-zero*/ #define UOP_CALL_INSTRUCTION_FUNC (UOP_TYPE_PARAMS_POINTER | 0x11 | UOP_TYPE_BARRIER) -#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) -#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) +#define UOP_STORE_P_IMM (UOP_TYPE_PARAMS_IMM | 0x12) +#define UOP_STORE_P_IMM_8 (UOP_TYPE_PARAMS_IMM | 0x13) /*UOP_LOAD_SEG - load segment in src_reg_a to segment p via loadseg(), check return value and exit block if non-zero*/ -#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) +#define UOP_LOAD_SEG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x14 | UOP_TYPE_BARRIER) /*UOP_JMP - jump to ptr*/ -#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) +#define UOP_JMP (UOP_TYPE_PARAMS_POINTER | 0x15 | UOP_TYPE_ORDER_BARRIER) /*UOP_CALL_FUNC - call instruction handler at p, dest_reg = return value*/ -#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) +#define UOP_CALL_FUNC_RESULT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x16 | UOP_TYPE_BARRIER) /*UOP_JMP_DEST - jump to ptr*/ -#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) -#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) -#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) +#define UOP_JMP_DEST (UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x17 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_NOP_BARRIER (UOP_TYPE_BARRIER | 0x18) +#define UOP_STORE_P_IMM_16 (UOP_TYPE_PARAMS_IMM | 0x19) #ifdef DEBUG_EXTRA /*UOP_LOG_INSTR - log non-recompiled instruction in imm_data*/ -#define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) +# define UOP_LOG_INSTR (UOP_TYPE_PARAMS_IMM | 0x1f) #endif /*UOP_MOV_PTR - dest_reg = p*/ -#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) +#define UOP_MOV_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x20) /*UOP_MOV_IMM - dest_reg = imm_data*/ -#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) +#define UOP_MOV_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x21) /*UOP_MOV - dest_reg = src_reg_a*/ -#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) +#define UOP_MOV (UOP_TYPE_PARAMS_REGS | 0x22) /*UOP_MOVZX - dest_reg = zero_extend(src_reg_a)*/ -#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) +#define UOP_MOVZX (UOP_TYPE_PARAMS_REGS | 0x23) /*UOP_MOVSX - dest_reg = sign_extend(src_reg_a)*/ -#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) +#define UOP_MOVSX (UOP_TYPE_PARAMS_REGS | 0x24) /*UOP_MOV_DOUBLE_INT - dest_reg = (double)src_reg_a*/ -#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) +#define UOP_MOV_DOUBLE_INT (UOP_TYPE_PARAMS_REGS | 0x25) /*UOP_MOV_INT_DOUBLE - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ -#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) +#define UOP_MOV_INT_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x26) /*UOP_MOV_INT_DOUBLE_64 - dest_reg = (int)src_reg_a. New rounding control in src_reg_b, old rounding control in src_reg_c*/ -#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) +#define UOP_MOV_INT_DOUBLE_64 (UOP_TYPE_PARAMS_REGS | 0x27) /*UOP_MOV_REG_PTR - dest_reg = *p*/ -#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) +#define UOP_MOV_REG_PTR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x28) /*UOP_MOVZX_REG_PTR_8 - dest_reg = *(uint8_t *)p*/ -#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) +#define UOP_MOVZX_REG_PTR_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x29) /*UOP_MOVZX_REG_PTR_16 - dest_reg = *(uint16_t *)p*/ -#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) +#define UOP_MOVZX_REG_PTR_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x2a) /*UOP_ADD - dest_reg = src_reg_a + src_reg_b*/ -#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) +#define UOP_ADD (UOP_TYPE_PARAMS_REGS | 0x30) /*UOP_ADD_IMM - dest_reg = src_reg_a + immediate*/ -#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) +#define UOP_ADD_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x31) /*UOP_AND - dest_reg = src_reg_a & src_reg_b*/ -#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) +#define UOP_AND (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x32) /*UOP_AND_IMM - dest_reg = src_reg_a & immediate*/ -#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) +#define UOP_AND_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x33) /*UOP_ADD_LSHIFT - dest_reg = src_reg_a + (src_reg_b << imm_data) Intended for EA calcluations, imm_data must be between 0 and 3*/ -#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) +#define UOP_ADD_LSHIFT (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x34) /*UOP_OR - dest_reg = src_reg_a | src_reg_b*/ -#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) +#define UOP_OR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x35) /*UOP_OR_IMM - dest_reg = src_reg_a | immediate*/ -#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) +#define UOP_OR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x36) /*UOP_SUB - dest_reg = src_reg_a - src_reg_b*/ -#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) +#define UOP_SUB (UOP_TYPE_PARAMS_REGS | 0x37) /*UOP_SUB_IMM - dest_reg = src_reg_a - immediate*/ -#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) +#define UOP_SUB_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x38) /*UOP_XOR - dest_reg = src_reg_a ^ src_reg_b*/ -#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) +#define UOP_XOR (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x39) /*UOP_XOR_IMM - dest_reg = src_reg_a ^ immediate*/ -#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) +#define UOP_XOR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3a) /*UOP_ANDN - dest_reg = ~src_reg_a & src_reg_b*/ -#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) +#define UOP_ANDN (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x3b) /*UOP_MEM_LOAD_ABS - dest_reg = src_reg_a:[immediate]*/ -#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x40 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_REG - dest_reg = src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_REG (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x41 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_ABS - src_reg_a:[immediate] = src_reg_b*/ -#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_ABS (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x42 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_REG - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_REG (UOP_TYPE_PARAMS_REGS | 0x43 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_8 - byte src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_8 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x44 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_16 - word src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_16 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x45 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_IMM_32 - long src_reg_a:[src_reg_b] = imm_data*/ -#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_IMM_32 (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x46 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_SINGLE - dest_reg = (float)src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_SINGLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x47 | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_IMM_JZ - if (src_reg_a == imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_IMM_JZ (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x48 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_LOAD_DOUBLE - dest_reg = (double)src_reg_a:[src_reg_b]*/ -#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_LOAD_DOUBLE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x49 | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_SINGLE - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_SINGLE (UOP_TYPE_PARAMS_REGS | 0x4a | UOP_TYPE_ORDER_BARRIER) /*UOP_MEM_STORE_DOUBLE - src_reg_a:[src_reg_b] = src_reg_c*/ -#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) +#define UOP_MEM_STORE_DOUBLE (UOP_TYPE_PARAMS_REGS | 0x4b | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_JB - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_JB (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4c | UOP_TYPE_ORDER_BARRIER) /*UOP_CMP_JNBE - if (src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) +#define UOP_CMP_JNBE (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_POINTER | 0x4d | UOP_TYPE_ORDER_BARRIER) /*UOP_SAR - dest_reg = src_reg_a >> src_reg_b*/ -#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) +#define UOP_SAR (UOP_TYPE_PARAMS_REGS | 0x50) /*UOP_SAR_IMM - dest_reg = src_reg_a >> immediate*/ -#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) +#define UOP_SAR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x51) /*UOP_SHL - dest_reg = src_reg_a << src_reg_b*/ -#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) +#define UOP_SHL (UOP_TYPE_PARAMS_REGS | 0x52) /*UOP_SHL_IMM - dest_reg = src_reg_a << immediate*/ -#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) +#define UOP_SHL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x53) /*UOP_SHR - dest_reg = src_reg_a >> src_reg_b*/ -#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) +#define UOP_SHR (UOP_TYPE_PARAMS_REGS | 0x54) /*UOP_SHR_IMM - dest_reg = src_reg_a >> immediate*/ -#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) +#define UOP_SHR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x55) /*UOP_ROL - dest_reg = src_reg_a rotate<< src_reg_b*/ -#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) +#define UOP_ROL (UOP_TYPE_PARAMS_REGS | 0x56) /*UOP_ROL_IMM - dest_reg = src_reg_a rotate<< immediate*/ -#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) +#define UOP_ROL_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x57) /*UOP_ROR - dest_reg = src_reg_a rotate>> src_reg_b*/ -#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) +#define UOP_ROR (UOP_TYPE_PARAMS_REGS | 0x58) /*UOP_ROR_IMM - dest_reg = src_reg_a rotate>> immediate*/ -#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) +#define UOP_ROR_IMM (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | 0x59) /*UOP_CMP_IMM_JZ_DEST - if (src_reg_a == imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_IMM_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x60 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_IMM_JNZ_DEST - if (src_reg_a != imm_data) then jump to ptr*/ -#define UOP_CMP_IMM_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_IMM_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x61 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JB_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x62 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNB_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNB_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x63 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JO_DEST - if (src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x64 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNO_DEST - if (src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNO_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x65 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JZ_DEST - if (src_reg_a == src_reg_b) then jump to ptr*/ -#define UOP_CMP_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x66 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNZ_DEST - if (src_reg_a != src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNZ_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x67 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JL_DEST - if (signed)(src_reg_a < src_reg_b) then jump to ptr*/ -#define UOP_CMP_JL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x68 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNL_DEST - if (signed)(src_reg_a >= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNL_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x69 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JBE_DEST - if (src_reg_a <= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6a | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNBE_DEST - if (src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JNBE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6b | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JLE_DEST - if (signed)(src_reg_a <= src_reg_b) then jump to ptr*/ -#define UOP_CMP_JLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_CMP_JLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6c | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_CMP_JNLE_DEST - if (signed)(src_reg_a > src_reg_b) then jump to ptr*/ -#define UOP_CMP_JNLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) - +#define UOP_CMP_JNLE_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x6d | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_TEST_JNS_DEST - if (src_reg_a positive) then jump to ptr*/ -#define UOP_TEST_JNS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_TEST_JNS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x70 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_TEST_JS_DEST - if (src_reg_a positive) then jump to ptr*/ -#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) +#define UOP_TEST_JS_DEST (UOP_TYPE_PARAMS_REGS | UOP_TYPE_PARAMS_IMM | UOP_TYPE_PARAMS_POINTER | 0x71 | UOP_TYPE_ORDER_BARRIER | UOP_TYPE_JUMP) /*UOP_FP_ENTER - must be called before any FPU register accessed*/ -#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) +#define UOP_FP_ENTER (UOP_TYPE_PARAMS_IMM | 0x80 | UOP_TYPE_BARRIER) /*UOP_FADD - (floating point) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) +#define UOP_FADD (UOP_TYPE_PARAMS_REGS | 0x81) /*UOP_FSUB - (floating point) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) +#define UOP_FSUB (UOP_TYPE_PARAMS_REGS | 0x82) /*UOP_FMUL - (floating point) dest_reg = src_reg_a * src_reg_b*/ -#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) +#define UOP_FMUL (UOP_TYPE_PARAMS_REGS | 0x83) /*UOP_FDIV - (floating point) dest_reg = src_reg_a / src_reg_b*/ -#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) +#define UOP_FDIV (UOP_TYPE_PARAMS_REGS | 0x84) /*UOP_FCOM - dest_reg = flags from compare(src_reg_a, src_reg_b)*/ -#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) +#define UOP_FCOM (UOP_TYPE_PARAMS_REGS | 0x85) /*UOP_FABS - dest_reg = fabs(src_reg_a)*/ -#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) +#define UOP_FABS (UOP_TYPE_PARAMS_REGS | 0x86) /*UOP_FCHS - dest_reg = fabs(src_reg_a)*/ -#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) +#define UOP_FCHS (UOP_TYPE_PARAMS_REGS | 0x87) /*UOP_FTST - dest_reg = flags from compare(src_reg_a, 0)*/ -#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) +#define UOP_FTST (UOP_TYPE_PARAMS_REGS | 0x88) /*UOP_FSQRT - dest_reg = fsqrt(src_reg_a)*/ -#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) +#define UOP_FSQRT (UOP_TYPE_PARAMS_REGS | 0x89) /*UOP_MMX_ENTER - must be called before any MMX registers accessed*/ -#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) +#define UOP_MMX_ENTER (UOP_TYPE_PARAMS_IMM | 0x90 | UOP_TYPE_BARRIER) /*UOP_PADDB - (packed byte) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) +#define UOP_PADDB (UOP_TYPE_PARAMS_REGS | 0x91) /*UOP_PADDW - (packed word) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) +#define UOP_PADDW (UOP_TYPE_PARAMS_REGS | 0x92) /*UOP_PADDD - (packed long) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) +#define UOP_PADDD (UOP_TYPE_PARAMS_REGS | 0x93) /*UOP_PADDSB - (packed byte with signed saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) +#define UOP_PADDSB (UOP_TYPE_PARAMS_REGS | 0x94) /*UOP_PADDSW - (packed word with signed saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) +#define UOP_PADDSW (UOP_TYPE_PARAMS_REGS | 0x95) /*UOP_PADDUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) +#define UOP_PADDUSB (UOP_TYPE_PARAMS_REGS | 0x96) /*UOP_PADDUSW - (packed word with unsigned saturation) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) +#define UOP_PADDUSW (UOP_TYPE_PARAMS_REGS | 0x97) /*UOP_PSUBB - (packed byte) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) +#define UOP_PSUBB (UOP_TYPE_PARAMS_REGS | 0x98) /*UOP_PSUBW - (packed word) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) +#define UOP_PSUBW (UOP_TYPE_PARAMS_REGS | 0x99) /*UOP_PSUBD - (packed long) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) +#define UOP_PSUBD (UOP_TYPE_PARAMS_REGS | 0x9a) /*UOP_PSUBSB - (packed byte with signed saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) +#define UOP_PSUBSB (UOP_TYPE_PARAMS_REGS | 0x9b) /*UOP_PSUBSW - (packed word with signed saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) +#define UOP_PSUBSW (UOP_TYPE_PARAMS_REGS | 0x9c) /*UOP_PSUBUSB - (packed byte with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) +#define UOP_PSUBUSB (UOP_TYPE_PARAMS_REGS | 0x9d) /*UOP_PSUBUSW - (packed word with unsigned saturation) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) +#define UOP_PSUBUSW (UOP_TYPE_PARAMS_REGS | 0x9e) /*UOP_PSLLW_IMM - (packed word) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) +#define UOP_PSLLW_IMM (UOP_TYPE_PARAMS_REGS | 0x9f) /*UOP_PSLLD_IMM - (packed long) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) +#define UOP_PSLLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa0) /*UOP_PSLLQ_IMM - (packed quad) dest_reg = src_reg_a << immediate*/ -#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) +#define UOP_PSLLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa1) /*UOP_PSRAW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) +#define UOP_PSRAW_IMM (UOP_TYPE_PARAMS_REGS | 0xa2) /*UOP_PSRAD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) +#define UOP_PSRAD_IMM (UOP_TYPE_PARAMS_REGS | 0xa3) /*UOP_PSRAQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) +#define UOP_PSRAQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa4) /*UOP_PSRLW_IMM - (packed word) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) +#define UOP_PSRLW_IMM (UOP_TYPE_PARAMS_REGS | 0xa5) /*UOP_PSRLD_IMM - (packed long) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) +#define UOP_PSRLD_IMM (UOP_TYPE_PARAMS_REGS | 0xa6) /*UOP_PSRLQ_IMM - (packed quad) dest_reg = src_reg_a >> immediate*/ -#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) +#define UOP_PSRLQ_IMM (UOP_TYPE_PARAMS_REGS | 0xa7) /*UOP_PCMPEQB - (packed byte) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) +#define UOP_PCMPEQB (UOP_TYPE_PARAMS_REGS | 0xa8) /*UOP_PCMPEQW - (packed word) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) +#define UOP_PCMPEQW (UOP_TYPE_PARAMS_REGS | 0xa9) /*UOP_PCMPEQD - (packed long) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) +#define UOP_PCMPEQD (UOP_TYPE_PARAMS_REGS | 0xaa) /*UOP_PCMPGTB - (packed signed byte) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) +#define UOP_PCMPGTB (UOP_TYPE_PARAMS_REGS | 0xab) /*UOP_PCMPGTW - (packed signed word) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) +#define UOP_PCMPGTW (UOP_TYPE_PARAMS_REGS | 0xac) /*UOP_PCMPGTD - (packed signed long) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) +#define UOP_PCMPGTD (UOP_TYPE_PARAMS_REGS | 0xad) /*UOP_PUNPCKLBW - (packed byte) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) +#define UOP_PUNPCKLBW (UOP_TYPE_PARAMS_REGS | 0xae) /*UOP_PUNPCKLWD - (packed word) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) +#define UOP_PUNPCKLWD (UOP_TYPE_PARAMS_REGS | 0xaf) /*UOP_PUNPCKLDQ - (packed long) dest_reg = interleave low src_reg_a/src_reg_b*/ -#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) +#define UOP_PUNPCKLDQ (UOP_TYPE_PARAMS_REGS | 0xb0) /*UOP_PUNPCKHBW - (packed byte) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) +#define UOP_PUNPCKHBW (UOP_TYPE_PARAMS_REGS | 0xb1) /*UOP_PUNPCKHWD - (packed word) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) +#define UOP_PUNPCKHWD (UOP_TYPE_PARAMS_REGS | 0xb2) /*UOP_PUNPCKHDQ - (packed long) dest_reg = interleave high src_reg_a/src_reg_b*/ -#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) +#define UOP_PUNPCKHDQ (UOP_TYPE_PARAMS_REGS | 0xb3) /*UOP_PACKSSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with signed saturation*/ -#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) +#define UOP_PACKSSWB (UOP_TYPE_PARAMS_REGS | 0xb4) /*UOP_PACKSSDW - dest_reg = interleave src_reg_a/src_reg_b, converting longs to words with signed saturation*/ -#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) +#define UOP_PACKSSDW (UOP_TYPE_PARAMS_REGS | 0xb5) /*UOP_PACKUSWB - dest_reg = interleave src_reg_a/src_reg_b, converting words to bytes with unsigned saturation*/ -#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) +#define UOP_PACKUSWB (UOP_TYPE_PARAMS_REGS | 0xb6) /*UOP_PMULLW - (packed word) dest_reg = (src_reg_a * src_reg_b) & 0xffff*/ -#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) +#define UOP_PMULLW (UOP_TYPE_PARAMS_REGS | 0xb7) /*UOP_PMULHW - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ -#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) +#define UOP_PMULHW (UOP_TYPE_PARAMS_REGS | 0xb8) /*UOP_PMADDWD - (packed word) dest_reg = (src_reg_a * src_reg_b) >> 16*/ -#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) +#define UOP_PMADDWD (UOP_TYPE_PARAMS_REGS | 0xb9) /*UOP_PFADD - (packed float) dest_reg = src_reg_a + src_reg_b*/ -#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) +#define UOP_PFADD (UOP_TYPE_PARAMS_REGS | 0xba) /*UOP_PFSUB - (packed float) dest_reg = src_reg_a - src_reg_b*/ -#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) +#define UOP_PFSUB (UOP_TYPE_PARAMS_REGS | 0xbb) /*UOP_PFMUL - (packed float) dest_reg = src_reg_a * src_reg_b*/ -#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) +#define UOP_PFMUL (UOP_TYPE_PARAMS_REGS | 0xbc) /*UOP_PFMAX - (packed float) dest_reg = MAX(src_reg_a, src_reg_b)*/ -#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) +#define UOP_PFMAX (UOP_TYPE_PARAMS_REGS | 0xbd) /*UOP_PFMIN - (packed float) dest_reg = MIN(src_reg_a, src_reg_b)*/ -#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) +#define UOP_PFMIN (UOP_TYPE_PARAMS_REGS | 0xbe) /*UOP_PFCMPEQ - (packed float) dest_reg = (src_reg_a == src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) +#define UOP_PFCMPEQ (UOP_TYPE_PARAMS_REGS | 0xbf) /*UOP_PFCMPGE - (packed float) dest_reg = (src_reg_a >= src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) +#define UOP_PFCMPGE (UOP_TYPE_PARAMS_REGS | 0xc0) /*UOP_PFCMPGT - (packed float) dest_reg = (src_reg_a > src_reg_b) ? ~0 : 0*/ -#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) +#define UOP_PFCMPGT (UOP_TYPE_PARAMS_REGS | 0xc1) /*UOP_PF2ID - (packed long)dest_reg = (packed float)src_reg_a*/ -#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) +#define UOP_PF2ID (UOP_TYPE_PARAMS_REGS | 0xc2) /*UOP_PI2FD - (packed float)dest_reg = (packed long)src_reg_a*/ -#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) +#define UOP_PI2FD (UOP_TYPE_PARAMS_REGS | 0xc3) /*UOP_PFRCP - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / src_reg[0]*/ -#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) +#define UOP_PFRCP (UOP_TYPE_PARAMS_REGS | 0xc4) /*UOP_PFRSQRT - (packed float) dest_reg[0] = dest_reg[1] = 1.0 / sqrt(src_reg[0])*/ -#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) +#define UOP_PFRSQRT (UOP_TYPE_PARAMS_REGS | 0xc5) -#define UOP_MAX 0xc6 +#define UOP_MAX 0xc6 #define UOP_INVALID 0xff -#define UOP_MASK 0xffff +#define UOP_MASK 0xffff -typedef struct uop_t -{ - uint32_t type; - ir_reg_t dest_reg_a; - ir_reg_t src_reg_a; - ir_reg_t src_reg_b; - ir_reg_t src_reg_c; - uint32_t imm_data; - void *p; - ir_host_reg_t dest_reg_a_real; - ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; - int jump_dest_uop; - int jump_list_next; - void *jump_dest; - uint32_t pc; +typedef struct uop_t { + uint32_t type; + ir_reg_t dest_reg_a; + ir_reg_t src_reg_a; + ir_reg_t src_reg_b; + ir_reg_t src_reg_c; + uint32_t imm_data; + void *p; + ir_host_reg_t dest_reg_a_real; + ir_host_reg_t src_reg_a_real, src_reg_b_real, src_reg_c_real; + int jump_dest_uop; + int jump_list_next; + void *jump_dest; + uint32_t pc; } uop_t; #define UOP_NR_MAX 4096 -typedef struct ir_data_t -{ - uop_t uops[UOP_NR_MAX]; - int wr_pos; - struct codeblock_t *block; +typedef struct ir_data_t { + uop_t uops[UOP_NR_MAX]; + int wr_pos; + struct codeblock_t *block; } ir_data_t; -static inline uop_t *uop_alloc(ir_data_t *ir, uint32_t uop_type) +static inline uop_t * +uop_alloc(ir_data_t *ir, uint32_t uop_type) { - uop_t *uop; + uop_t *uop; - if (ir->wr_pos >= UOP_NR_MAX) - fatal("Exceeded uOP max\n"); + if (ir->wr_pos >= UOP_NR_MAX) + fatal("Exceeded uOP max\n"); - uop = &ir->uops[ir->wr_pos++]; + uop = &ir->uops[ir->wr_pos++]; - uop->dest_reg_a = invalid_ir_reg; - uop->src_reg_a = invalid_ir_reg; - uop->src_reg_b = invalid_ir_reg; - uop->src_reg_c = invalid_ir_reg; + uop->dest_reg_a = invalid_ir_reg; + uop->src_reg_a = invalid_ir_reg; + uop->src_reg_b = invalid_ir_reg; + uop->src_reg_c = invalid_ir_reg; - uop->pc = cpu_state.oldpc; + uop->pc = cpu_state.oldpc; - uop->jump_dest_uop = -1; - uop->jump_list_next = -1; + uop->jump_dest_uop = -1; + uop->jump_list_next = -1; - if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) - codegen_reg_mark_as_required(); + if (uop_type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER)) + codegen_reg_mark_as_required(); - return uop; + return uop; } -static inline void uop_set_jump_dest(ir_data_t *ir, int jump_uop) +static inline void +uop_set_jump_dest(ir_data_t *ir, int jump_uop) { - uop_t *uop = &ir->uops[jump_uop]; + uop_t *uop = &ir->uops[jump_uop]; - uop->jump_dest_uop = ir->wr_pos; + uop->jump_dest_uop = ir->wr_pos; } -static inline int uop_gen(uint32_t uop_type, ir_data_t *ir) +static inline int +uop_gen(uint32_t uop_type, ir_data_t *ir) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; + uop->type = uop_type; - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline int uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) +static inline int +uop_gen_reg_src1(uint32_t uop_type, ir_data_t *ir, int src_reg_a) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) +static inline void +uop_gen_reg_src1_arg(uint32_t uop_type, ir_data_t *ir, int arg, int src_reg_a) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); } -static inline int uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) +static inline int +uop_gen_reg_src1_imm(uint32_t uop_type, ir_data_t *ir, int src_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->imm_data = imm; - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) +static inline void +uop_gen_reg_dst_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline void uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) +static inline void +uop_gen_reg_dst_pointer(uint32_t uop_type, ir_data_t *ir, int dest_reg, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->p = p; + uop->type = uop_type; + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->p = p; } -static inline void uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) +static inline void +uop_gen_reg_dst_src1(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) +static inline void +uop_gen_reg_dst_src1_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline void uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) +static inline void +uop_gen_reg_dst_src2(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) +static inline void +uop_gen_reg_dst_src2_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline void uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) +static inline void +uop_gen_reg_dst_src3(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg_a, int src_reg_b, int src_reg_c) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->src_reg_c = codegen_reg_read(src_reg_c); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); } -static inline void uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) +static inline void +uop_gen_reg_dst_src_imm(uint32_t uop_type, ir_data_t *ir, int dest_reg, int src_reg, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg); - uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg); + uop->dest_reg_a = codegen_reg_write(dest_reg, ir->wr_pos - 1); + uop->imm_data = imm; } -static inline int uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) +static inline int +uop_gen_reg_src2(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); - return ir->wr_pos-1; + return ir->wr_pos - 1; } -static inline void uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) +static inline void +uop_gen_reg_src2_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->imm_data = imm; } -static inline void uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) +static inline void +uop_gen_reg_src3(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); } -static inline void uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) +static inline void +uop_gen_reg_src3_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, int src_reg_c, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->src_reg_c = codegen_reg_read(src_reg_c); - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->src_reg_c = codegen_reg_read(src_reg_c); + uop->imm_data = imm; } -static inline void uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) +static inline void +uop_gen_imm(uint32_t uop_type, ir_data_t *ir, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->imm_data = imm; + uop->type = uop_type; + uop->imm_data = imm; } -static inline void uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) +static inline void +uop_gen_pointer(uint32_t uop_type, ir_data_t *ir, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->p = p; + uop->type = uop_type; + uop->p = p; } -static inline void uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) +static inline void +uop_gen_pointer_imm(uint32_t uop_type, ir_data_t *ir, void *p, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->p = p; - uop->imm_data = imm; + uop->type = uop_type; + uop->p = p; + uop->imm_data = imm; } -static inline void uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) +static inline void +uop_gen_reg_src_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->p = p; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->p = p; } -static inline void uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) +static inline void +uop_gen_reg_src_pointer_imm(uint32_t uop_type, ir_data_t *ir, int src_reg_a, void *p, uint32_t imm) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->p = p; - uop->imm_data = imm; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->p = p; + uop->imm_data = imm; } -static inline void uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) +static inline void +uop_gen_reg_src2_pointer(uint32_t uop_type, ir_data_t *ir, int src_reg_a, int src_reg_b, void *p) { - uop_t *uop = uop_alloc(ir, uop_type); + uop_t *uop = uop_alloc(ir, uop_type); - uop->type = uop_type; - uop->src_reg_a = codegen_reg_read(src_reg_a); - uop->src_reg_b = codegen_reg_read(src_reg_b); - uop->p = p; + uop->type = uop_type; + uop->src_reg_a = codegen_reg_read(src_reg_a); + uop->src_reg_b = codegen_reg_read(src_reg_b); + uop->p = p; } -#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) +#define uop_LOAD_FUNC_ARG_REG(ir, arg, reg) uop_gen_reg_src1(UOP_LOAD_FUNC_ARG_0 + arg, ir, reg) -#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) +#define uop_LOAD_FUNC_ARG_IMM(ir, arg, imm) uop_gen_imm(UOP_LOAD_FUNC_ARG_0_IMM + arg, ir, imm) -#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) +#define uop_ADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_ADD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ADD_IMM, ir, dst_reg, src_reg, imm) #define uop_ADD_LSHIFT(ir, dst_reg, src_reg_a, src_reg_b, shift) uop_gen_reg_dst_src2_imm(UOP_ADD_LSHIFT, ir, dst_reg, src_reg_a, src_reg_b, shift) -#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) -#define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) -#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) +#define uop_AND(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_AND, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_AND_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_AND_IMM, ir, dst_reg, src_reg, imm) +#define uop_ANDN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_ANDN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_OR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_OR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_OR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_SUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_SUB_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SUB_IMM, ir, dst_reg, src_reg, imm) +#define uop_XOR(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_XOR, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_XOR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_XOR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) -#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) -#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) -#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) -#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) -#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) -#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) -#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) -#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) -#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SAR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SAR, ir, dst_reg, src_reg, shift_reg) +#define uop_SAR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SAR_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHL, ir, dst_reg, src_reg, shift_reg) +#define uop_SHL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHL_IMM, ir, dst_reg, src_reg, imm) +#define uop_SHR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_SHR, ir, dst_reg, src_reg, shift_reg) +#define uop_SHR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_SHR_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROL(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROL, ir, dst_reg, src_reg, shift_reg) +#define uop_ROL_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROL_IMM, ir, dst_reg, src_reg, imm) +#define uop_ROR(ir, dst_reg, src_reg, shift_reg) uop_gen_reg_dst_src2(UOP_ROR, ir, dst_reg, src_reg, shift_reg) +#define uop_ROR_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_ROR_IMM, ir, dst_reg, src_reg, imm) -#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) -#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) -#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) +#define uop_CALL_FUNC(ir, p) uop_gen_pointer(UOP_CALL_FUNC, ir, p) +#define uop_CALL_FUNC_RESULT(ir, dst_reg, p) uop_gen_reg_dst_pointer(UOP_CALL_FUNC_RESULT, ir, dst_reg, p) +#define uop_CALL_INSTRUCTION_FUNC(ir, p) uop_gen_pointer(UOP_CALL_INSTRUCTION_FUNC, ir, p) -#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) +#define uop_CMP_IMM_JZ(ir, src_reg, imm, p) uop_gen_reg_src_pointer_imm(UOP_CMP_IMM_JZ, ir, src_reg, p, imm) -#define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) -#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) +#define uop_CMP_IMM_JNZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JNZ_DEST, ir, src_reg, imm) +#define uop_CMP_IMM_JZ_DEST(ir, src_reg, imm) uop_gen_reg_src1_imm(UOP_CMP_IMM_JZ_DEST, ir, src_reg, imm) -#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) -#define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p) +#define uop_CMP_JB(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JB, ir, src_reg_a, src_reg_b, p) +#define uop_CMP_JNBE(ir, src_reg_a, src_reg_b, p) uop_gen_reg_src2_pointer(UOP_CMP_JNBE, ir, src_reg_a, src_reg_b, p) -#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNLE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) -#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JNZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JNZ_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JB_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JB_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JBE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JBE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JL_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JL_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JLE_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JLE_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JO_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JO_DEST, ir, src_reg_a, src_reg_b) +#define uop_CMP_JZ_DEST(ir, src_reg_a, src_reg_b) uop_gen_reg_src2(UOP_CMP_JZ_DEST, ir, src_reg_a, src_reg_b) -#define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FCOM(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FCOM, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FDIV(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FDIV, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FCOM(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FCOM, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FDIV(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FDIV, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_FSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_FSUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_FABS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FABS, ir, dst_reg, src_reg) -#define uop_FCHS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FCHS, ir, dst_reg, src_reg) -#define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) -#define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) +#define uop_FABS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FABS, ir, dst_reg, src_reg) +#define uop_FCHS(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FCHS, ir, dst_reg, src_reg) +#define uop_FSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FSQRT, ir, dst_reg, src_reg) +#define uop_FTST(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_FTST, ir, dst_reg, src_reg) -#define uop_FP_ENTER(ir) do { if (!codegen_fpu_entered) uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); codegen_fpu_entered = 1; codegen_mmx_entered = 0; } while (0) -#define uop_MMX_ENTER(ir) do { if (!codegen_mmx_entered) uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); codegen_mmx_entered = 1; codegen_fpu_entered = 0; } while (0) +#define uop_FP_ENTER(ir) \ + do { \ + if (!codegen_fpu_entered) \ + uop_gen_imm(UOP_FP_ENTER, ir, cpu_state.oldpc); \ + codegen_fpu_entered = 1; \ + codegen_mmx_entered = 0; \ + } while (0) +#define uop_MMX_ENTER(ir) \ + do { \ + if (!codegen_mmx_entered) \ + uop_gen_imm(UOP_MMX_ENTER, ir, cpu_state.oldpc); \ + codegen_mmx_entered = 1; \ + codegen_fpu_entered = 0; \ + } while (0) -#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) -#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) +#define uop_JMP(ir, p) uop_gen_pointer(UOP_JMP, ir, p) +#define uop_JMP_DEST(ir) uop_gen(UOP_JMP_DEST, ir) -#define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) +#define uop_LOAD_SEG(ir, p, src_reg) uop_gen_reg_src_pointer(UOP_LOAD_SEG, ir, src_reg, p) -#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) -#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) -#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) -#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) -#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_LOAD_ABS(ir, dst_reg, seg_reg, imm) uop_gen_reg_dst_src_imm(UOP_MEM_LOAD_ABS, ir, dst_reg, seg_reg, imm) +#define uop_MEM_LOAD_REG(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_REG_OFFSET(ir, dst_reg, seg_reg, addr_reg, offset) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_REG, ir, dst_reg, seg_reg, addr_reg, offset) +#define uop_MEM_LOAD_SINGLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_SINGLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_LOAD_DOUBLE(ir, dst_reg, seg_reg, addr_reg) uop_gen_reg_dst_src2_imm(UOP_MEM_LOAD_DOUBLE, ir, dst_reg, seg_reg, addr_reg, 0) +#define uop_MEM_STORE_ABS(ir, seg_reg, imm, src_reg) uop_gen_reg_src2_imm(UOP_MEM_STORE_ABS, ir, seg_reg, src_reg, imm) +#define uop_MEM_STORE_REG(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, 0) #define uop_MEM_STORE_REG_OFFSET(ir, seg_reg, addr_reg, offset, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_REG, ir, seg_reg, addr_reg, src_reg, offset) -#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) -#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_IMM_8(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_8, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_IMM_16(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_16, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_IMM_32(ir, seg_reg, addr_reg, imm) uop_gen_reg_src2_imm(UOP_MEM_STORE_IMM_32, ir, seg_reg, addr_reg, imm) +#define uop_MEM_STORE_SINGLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_SINGLE, ir, seg_reg, addr_reg, src_reg, 0) +#define uop_MEM_STORE_DOUBLE(ir, seg_reg, addr_reg, src_reg) uop_gen_reg_src3_imm(UOP_MEM_STORE_DOUBLE, ir, seg_reg, addr_reg, src_reg, 0) -#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) -#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) -#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) -#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) -#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) -#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) -#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) -#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) -#define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) -#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg/*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg/*, nrc, orc*/) -#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) +#define uop_MOV(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV, ir, dst_reg, src_reg) +#define uop_MOV_IMM(ir, reg, imm) uop_gen_reg_dst_imm(UOP_MOV_IMM, ir, reg, imm) +#define uop_MOV_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_PTR, ir, reg, p) +#define uop_MOV_REG_PTR(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOV_REG_PTR, ir, reg, p) +#define uop_MOVZX_REG_PTR_8(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_8, ir, reg, p) +#define uop_MOVZX_REG_PTR_16(ir, reg, p) uop_gen_reg_dst_pointer(UOP_MOVZX_REG_PTR_16, ir, reg, p) +#define uop_MOVSX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVSX, ir, dst_reg, src_reg) +#define uop_MOVZX(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOVZX, ir, dst_reg, src_reg) +#define uop_MOV_DOUBLE_INT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_MOV_DOUBLE_INT, ir, dst_reg, src_reg) +#define uop_MOV_INT_DOUBLE(ir, dst_reg, src_reg /*, nrc, orc*/) uop_gen_reg_dst_src1(UOP_MOV_INT_DOUBLE, ir, dst_reg, src_reg /*, nrc, orc*/) +#define uop_MOV_INT_DOUBLE_64(ir, dst_reg, src_reg_d, src_reg_q, tag) uop_gen_reg_dst_src3(UOP_MOV_INT_DOUBLE_64, ir, dst_reg, src_reg_d, src_reg_q, tag) -#define uop_NOP_BARRIER(ir) uop_gen(UOP_NOP_BARRIER, ir) +#define uop_NOP_BARRIER(ir) uop_gen(UOP_NOP_BARRIER, ir) -#define uop_PACKSSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSWB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKSSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSWB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKSSDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKSSDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PACKUSWB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PACKUSWB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PADDUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PADDUSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPEQB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPEQW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPEQD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPGTB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPEQD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPEQD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PCMPGTD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PCMPGTD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) -#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFCMPEQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPEQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFCMPGE(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGE, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFCMPGT(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGT, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) -#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) -#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) +#define uop_PF2ID(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PF2ID, ir, dst_reg, src_reg) +#define uop_PFADD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFADD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPEQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPEQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPGE(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGE, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFCMPGT(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFCMPGT, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMAX(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMAX, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMIN(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMIN, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFMUL(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFMUL, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PFRCP(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRCP, ir, dst_reg, src_reg) +#define uop_PFRSQRT(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PFRSQRT, ir, dst_reg, src_reg) +#define uop_PFSUB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PFSUB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PI2FD(ir, dst_reg, src_reg) uop_gen_reg_dst_src1(UOP_PI2FD, ir, dst_reg, src_reg) -#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMADDWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMADDWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULHW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULHW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PMULLW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PMULLW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSLLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSLLQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRAQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRAQ_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLW_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLW_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLD_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLD_IMM, ir, dst_reg, src_reg, imm) +#define uop_PSRLQ_IMM(ir, dst_reg, src_reg, imm) uop_gen_reg_dst_src_imm(UOP_PSRLQ_IMM, ir, dst_reg, src_reg, imm) -#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBSW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBUSB(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSB, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PSUBUSW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PSUBUSW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKHBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKHWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKHDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHDQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKLBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLBW, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKLWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLWD, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_PUNPCKLDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLDQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKHDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKHDQ, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLBW(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLBW, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLWD(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLWD, ir, dst_reg, src_reg_a, src_reg_b) +#define uop_PUNPCKLDQ(ir, dst_reg, src_reg_a, src_reg_b) uop_gen_reg_dst_src2(UOP_PUNPCKLDQ, ir, dst_reg, src_reg_a, src_reg_b) -#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) -#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) -#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) +#define uop_STORE_PTR_IMM(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM, ir, p, imm) +#define uop_STORE_PTR_IMM_8(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_8, ir, p, imm) +#define uop_STORE_PTR_IMM_16(ir, p, imm) uop_gen_pointer_imm(UOP_STORE_P_IMM_16, ir, p, imm) -#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) -#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) +#define uop_TEST_JNS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JNS_DEST, ir, src_reg) +#define uop_TEST_JS_DEST(ir, src_reg) uop_gen_reg_src1(UOP_TEST_JS_DEST, ir, src_reg) #ifdef DEBUG_EXTRA -#define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) +# define uop_LOG_INSTR(ir, imm) uop_gen_imm(UOP_LOG_INSTR, ir, imm) #endif void codegen_direct_read_8(codeblock_t *block, int host_reg, void *p); diff --git a/src/codegen_new/codegen_ops.h b/src/codegen_new/codegen_ops.h index 361479b6d..9cef07e15 100644 --- a/src/codegen_new/codegen_ops.h +++ b/src/codegen_new/codegen_ops.h @@ -29,21 +29,21 @@ extern RecompOpFn recomp_opcodes_REPNE[512];*/ #define REG_EBP 5 #define REG_ESI 6 #define REG_EDI 7 -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 -#define REG_AL 0 -#define REG_AH 4 -#define REG_CL 1 -#define REG_CH 5 -#define REG_DL 2 -#define REG_DH 6 -#define REG_BL 3 -#define REG_BH 7 +#define REG_AX 0 +#define REG_CX 1 +#define REG_DX 2 +#define REG_BX 3 +#define REG_SP 4 +#define REG_BP 5 +#define REG_SI 6 +#define REG_DI 7 +#define REG_AL 0 +#define REG_AH 4 +#define REG_CL 1 +#define REG_CH 5 +#define REG_DL 2 +#define REG_DH 6 +#define REG_BL 3 +#define REG_BH 7 #endif diff --git a/src/codegen_new/codegen_ops_3dnow.c b/src/codegen_new/codegen_ops_3dnow.c index 2c4ecc353..ff0c136e2 100644 --- a/src/codegen_new/codegen_ops_3dnow.c +++ b/src/codegen_new/codegen_ops_3dnow.c @@ -13,199 +13,184 @@ #include "codegen_ops_3dnow.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - codegen_mark_code_present(block, cs+op_pc+1, 1); \ - return op_pc + 2; \ -} +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + codegen_mark_code_present(block, cs + op_pc + 1, 1); \ + return op_pc + 2; \ + } ropParith(PFADD) -ropParith(PFCMPEQ) -ropParith(PFCMPGE) -ropParith(PFCMPGT) -ropParith(PFMAX) -ropParith(PFMIN) -ropParith(PFMUL) -ropParith(PFSUB) + ropParith(PFCMPEQ) + ropParith(PFCMPGE) + ropParith(PFCMPGT) + ropParith(PFMAX) + ropParith(PFMIN) + ropParith(PFMUL) + ropParith(PFSUB) -uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + uint32_t ropPF2ID(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PF2ID(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_MM(src_reg), IREG_MM(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFSUB(ir, IREG_MM(dest_reg), IREG_temp0_Q, IREG_MM(dest_reg)); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPI2FD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PI2FD(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRCPIT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRCP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRCP(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_PFRSQRT(ir, IREG_MM(dest_reg), IREG_temp0_Q); + } - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPFRSQIT1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MMX_ENTER(ir); + uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } diff --git a/src/codegen_new/codegen_ops_arith.c b/src/codegen_new/codegen_ops_arith.c index 66715730d..5325b282b 100644 --- a/src/codegen_new/codegen_ops_arith.c +++ b/src/codegen_new/codegen_ops_arith.c @@ -12,2509 +12,2378 @@ #include "codegen_ops_arith.h" #include "codegen_ops_helpers.h" -static inline void get_cf(ir_data_t *ir, int dest_reg) +static inline void +get_cf(ir_data_t *ir, int dest_reg) { - uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); + uop_CALL_FUNC_RESULT(ir, dest_reg, CF_SET); } -uint32_t ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADC_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADC_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_ADD(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADC_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + fetchdat = fastreadl(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; +} +uint32_t +ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } + + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } + + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } + + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; +} +uint32_t +ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { fetchdat = fastreadl(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + codegen_mark_code_present(block, cs + op_pc, 4); + } - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + codegen_flags_changed = 1; + return op_pc + 4; } -uint32_t ropADC_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); - uop_ADD(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); - uop_ADD(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADC_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } - - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropADC_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); - uop_ADD(ir, IREG_temp2, IREG_temp2, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp2); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_ADD_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropADD_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_ADD_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropADD_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV(ir, IREG_flags_op1, IREG_EAX); + fetchdat = fastreadl(cs + op_pc); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_ADD(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - uop_ADD_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - codegen_mark_code_present(block, cs+op_pc, 4); - } + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropADD_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); + } + + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint8_t imm_data = fastreadb(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm_data = fastreadw(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; +} +uint32_t +ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + fetchdat = fastreadl(cs + op_pc); + + get_cf(ir, IREG_temp0); + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; +} +uint32_t +ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } + + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); + uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); + uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropADD_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + get_cf(ir, IREG_temp1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropADD_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); + uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp2); + } - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropCMP_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_AL, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_op1, IREG_AL); + uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropCMP_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_AX, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_op1, IREG_AX); + uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op2, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropCMP_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { + uop_MOV(ir, IREG_flags_op1, IREG_EAX); + + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { fetchdat = fastreadl(cs + op_pc); - - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - uop_SUB_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; -} -uint32_t ropCMP_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_flags_res_B, IREG_temp0_B, IREG_8(src_reg)); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_16(src_reg)); - } - - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropCMP_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_32(src_reg)); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropSBB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint8_t imm_data = fastreadb(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_SUB(ir, IREG_AL, IREG_AL, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} -uint32_t ropSBB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm_data = fastreadw(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_SUB(ir, IREG_AX, IREG_AX, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; -} -uint32_t ropSBB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - fetchdat = fastreadl(cs + op_pc); - - get_cf(ir, IREG_temp0); - uop_MOV(ir, IREG_flags_op1, IREG_EAX); + codegen_mark_code_present(block, cs + op_pc, 4); uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + } - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); + + codegen_flags_changed = 1; + return op_pc + 4; } -uint32_t ropSBB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2_B, IREG_temp0_B, IREG_8(src_reg)); - uop_SUB(ir, IREG_temp2_B, IREG_temp2_B, IREG_temp1_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2_W, IREG_temp0_W, IREG_16(src_reg)); - uop_SUB(ir, IREG_temp2_W, IREG_temp2_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_temp2_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); - } - - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSBB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int skip_immediate = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - get_cf(ir, IREG_temp1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint8_t imm = fastreadb(cs + op_pc + 1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp2, IREG_temp0, IREG_32(src_reg)); - uop_SUB(ir, IREG_temp2, IREG_temp2, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp2); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_temp2); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs + op_pc + 1); } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropSUB_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint8_t imm_data = fastreadb(cs + op_pc); - - uop_MOVZX(ir, IREG_flags_op1, IREG_AL); - uop_SUB_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} -uint32_t ropSUB_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm_data = fastreadw(cs + op_pc); - - uop_MOVZX(ir, IREG_flags_op1, IREG_AX); - uop_SUB_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op2, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; -} -uint32_t ropSUB_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uop_MOV(ir, IREG_flags_op1, IREG_EAX); - - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_SUB(ir, IREG_EAX, IREG_EAX, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_SUB_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - uop_MOV_IMM(ir, IREG_flags_op2, fetchdat); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); - - codegen_flags_changed = 1; - return op_pc + 4; -} -uint32_t ropSUB_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropSUB_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + else + uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + } else { + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint8_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); else - { - x86seg *target_seg; + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1_B, IREG_temp0_B, IREG_8(src_reg)); + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_8(src_reg)); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; - codegen_flags_changed = 1; - return op_pc + 1; + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropSUB_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int skip_immediate = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint16_t imm = fastreadw(cs + op_pc + 1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs + op_pc + 1); } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropSUB_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + else + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + } else { + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint16_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); else - { - x86seg *target_seg; + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs + op_pc + 1); + } - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_16(src_reg)); + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_16(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp3); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x28: /*SUB*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); + else + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); + else + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); + uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); + } else { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + } + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; } + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; } -uint32_t ropSUB_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int skip_immediate = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint32_t imm = fastreadl(cs + op_pc + 1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_flags_op2, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_flags_op2); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc + 1); } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropSUB_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + else + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + } else { + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint32_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); else - { - x86seg *target_seg; + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + skip_immediate = 1; + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs + op_pc + 1); + } - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_32(src_reg)); + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_32(src_reg)); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t rop80(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int skip_immediate = 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint8_t imm = fastreadb(cs + op_pc + 1); + break; + case 0x08: /*OR*/ if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp0_B, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_OR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_ADD_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_AND_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_SUB_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - else - uop_XOR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - } - else - { - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_8(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint8_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_ADD(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, IREG_temp2_B); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; - - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_B, IREG_temp0_B, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_B, IREG_temp0_B, imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; -} -uint32_t rop81_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int skip_immediate = 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint16_t imm = fastreadw(cs + op_pc + 1); + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp3); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp0_W, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - else - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - } - else - { - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint16_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadw(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_16(block, ir, IREG_temp2_W, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp3_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x28: /*SUB*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2_W); - else - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2_W); - else - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_MOVZX(ir, IREG_flags_op2, IREG_temp2_W); - uop_SUB(ir, IREG_flags_res_W, IREG_temp0_W, IREG_temp2_W); - } - else - { - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); - } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs+op_pc+1, 2); - return op_pc + 3; -} -uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int skip_immediate = 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint32_t imm = fastreadl(cs + op_pc + 1); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp3); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - else - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_SUB(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - } - else - { - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint32_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadl(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - skip_immediate = 1; - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp2, cs+op_pc+1); - } - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x08: /*OR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_ADD(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp3); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x20: /*AND*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x28: /*SUB*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); - else - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - else - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x30: /*XOR*/ - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - else - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); - } - else - { - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - if (!skip_immediate) - codegen_mark_code_present(block, cs+op_pc+1, 4); - return op_pc + 5; -} - -uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint16_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = (int16_t)(int8_t)fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - break; - - case 0x38: /*CMP*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; -} -uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SUB*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - uint32_t imm; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x38) == 0x38) /*CMP*/ - codegen_check_seg_read(block, ir, target_seg); + case 0x20: /*AND*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_temp2); else - codegen_check_seg_write(block, ir, target_seg); - imm = (int32_t)(int8_t)fastreadb(cs + op_pc + 1); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - switch (fetchdat & 0x38) - { - case 0x00: /*ADD*/ - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; + case 0x28: /*SUB*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_SUB(ir, IREG_temp1, IREG_temp0, IREG_temp2); + else + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + else + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; - case 0x08: /*OR*/ - uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; + case 0x30: /*XOR*/ + if (block->flags & CODEBLOCK_NO_IMMEDIATES) + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + else + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; - case 0x10: /*ADC*/ - get_cf(ir, IREG_temp2); - uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x18: /*SBB*/ - get_cf(ir, IREG_temp2); - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x20: /*AND*/ - uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x28: /*SUB*/ - uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x30: /*XOR*/ - uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - break; - - case 0x38: /*CMP*/ - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - break; - - default: - return 0; + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_SUB(ir, IREG_flags_res, IREG_temp0, IREG_temp2); + } else { + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); } - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + default: + return 0; + } + } + + codegen_flags_changed = 1; + if (!skip_immediate) + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; } -static void rebuild_c(ir_data_t *ir) +uint32_t +rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int needs_rebuild = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint16_t imm = (int16_t) (int8_t) fastreadb(cs + op_pc + 1); - if (codegen_flags_changed) - { - switch (cpu_state.flags_op) - { - case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: - case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: - needs_rebuild = 0; - break; - } - } + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; - if (needs_rebuild) - { - uop_CALL_FUNC(ir, flags_rebuild_c); + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_ADD_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_16(dest_reg), imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; } + } else { + x86seg *target_seg; + uint16_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = (int16_t) (int8_t) fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_ADD(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, IREG_temp2_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0_W, IREG_temp0_W, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + break; + + case 0x38: /*CMP*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res_W, IREG_temp0_W, imm); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; +} +uint32_t +rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uint32_t imm = (int32_t) (int8_t) fastreadb(cs + op_pc + 1); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_ADD_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_ADD(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SUB*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SUB_IMM(ir, IREG_flags_res, IREG_32(dest_reg), imm); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + uint32_t imm; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x38) == 0x38) /*CMP*/ + codegen_check_seg_read(block, ir, target_seg); + else + codegen_check_seg_write(block, ir, target_seg); + imm = (int32_t) (int8_t) fastreadb(cs + op_pc + 1); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ADD*/ + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADD32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x08: /*OR*/ + uop_OR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x10: /*ADC*/ + get_cf(ir, IREG_temp2); + uop_ADD_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_ADD(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ADC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x18: /*SBB*/ + get_cf(ir, IREG_temp2); + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_SUB(ir, IREG_temp1, IREG_temp1, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SBC32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x20: /*AND*/ + uop_AND_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x28: /*SUB*/ + uop_SUB_IMM(ir, IREG_temp1, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x30: /*XOR*/ + uop_XOR_IMM(ir, IREG_temp0, IREG_temp0, imm); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + break; + + case 0x38: /*CMP*/ + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SUB_IMM(ir, IREG_flags_res, IREG_temp0, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static void +rebuild_c(ir_data_t *ir) { - rebuild_c(ir); + int needs_rebuild = 1; - uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); - uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); - uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + if (codegen_flags_changed) { + switch (cpu_state.flags_op) { + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) { + uop_CALL_FUNC(ir, flags_rebuild_c); + } +} + +uint32_t +ropINC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_ADD_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t +ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t +ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); + uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); + uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + codegen_flags_changed = 1; + + return op_pc; +} +uint32_t +ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + rebuild_c(ir); + + uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); + uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); + uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + codegen_flags_changed = 1; + + return op_pc; +} + +uint32_t +ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + codegen_mark_code_present(block, cs + op_pc, 1); + rebuild_c(ir); + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); + if (fetchdat & 0x38) { + uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } else { + uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); + } + uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - codegen_flags_changed = 1; + } else { + x86seg *target_seg; - return op_pc; -} -uint32_t ropINC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - rebuild_c(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); - uop_ADD_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); - uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - codegen_flags_changed = 1; - - return op_pc; -} - -uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - rebuild_c(ir); - - uop_MOVZX(ir, IREG_flags_op1, IREG_16(opcode & 7)); - uop_SUB_IMM(ir, IREG_16(opcode & 7), IREG_16(opcode & 7), 1); - uop_MOVZX(ir, IREG_flags_res, IREG_16(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - codegen_flags_changed = 1; - - return op_pc; -} -uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - rebuild_c(ir); - - uop_MOV(ir, IREG_flags_op1, IREG_32(opcode & 7)); - uop_SUB_IMM(ir, IREG_32(opcode & 7), IREG_32(opcode & 7), 1); - uop_MOV(ir, IREG_flags_res, IREG_32(opcode & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - codegen_flags_changed = 1; - - return op_pc; -} - -uint32_t ropINCDEC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - codegen_mark_code_present(block, cs+op_pc, 1); - rebuild_c(ir); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op1, IREG_8(fetchdat & 7)); - if (fetchdat & 0x38) - { - uop_SUB_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); - } - else - { - uop_ADD_IMM(ir, IREG_8(fetchdat & 7), IREG_8(fetchdat & 7), 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); - } - uop_MOVZX(ir, IREG_flags_res, IREG_8(fetchdat & 7)); - uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) { + uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); + } else { + uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - - if (fetchdat & 0x38) - { - uop_SUB_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); - } - else - { - uop_ADD_IMM(ir, IREG_temp1_B, IREG_temp0_B, 1); - } - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - if (fetchdat & 0x38) - { - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); - } - else - { - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); - } + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + if (fetchdat & 0x38) { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC8); + } else { + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC8); } + } - return op_pc+1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_arith.h b/src/codegen_new/codegen_ops_arith.h index d1bbaa75d..176d4be7a 100644 --- a/src/codegen_new/codegen_ops_arith.h +++ b/src/codegen_new/codegen_ops_arith.h @@ -54,7 +54,6 @@ uint32_t rop81_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fet uint32_t rop83_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t rop83_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); - uint32_t ropDEC_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); uint32_t ropDEC_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc); diff --git a/src/codegen_new/codegen_ops_branch.c b/src/codegen_new/codegen_ops_branch.c index 70bfc1b10..85ebd3f8e 100644 --- a/src/codegen_new/codegen_ops_branch.c +++ b/src/codegen_new/codegen_ops_branch.c @@ -13,1002 +13,977 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -static int NF_SET_01(void) +static int +NF_SET_01(void) { - return NF_SET() ? 1 : 0; + return NF_SET() ? 1 : 0; } -static int VF_SET_01(void) +static int +VF_SET_01(void) { - return VF_SET() ? 1 : 0; + return VF_SET() ? 1 : 0; } -static int ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +static int +ropJO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Overflow is always zero*/ - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Overflow is always zero*/ + return 0; - case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + case FLAGS_DEC16: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + case FLAGS_DEC32: + jump_uop = uop_CMP_JNO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; } -static int ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +static int +ropJNO_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; + int jump_uop; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Overflow is always zero*/ - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Overflow is always zero*/ + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + return 0; - case FLAGS_SUB8: case FLAGS_DEC8: - jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + case FLAGS_DEC8: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; - case FLAGS_SUB16: case FLAGS_DEC16: - jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; + case FLAGS_SUB16: + case FLAGS_DEC16: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; - case FLAGS_SUB32: case FLAGS_DEC32: - jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; + case FLAGS_SUB32: + case FLAGS_DEC32: + jump_uop = uop_CMP_JO_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, VF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; +} + +static int +ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero*/ + return 0; + + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + if (do_unroll) jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} +static int +ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero*/ + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + return 0; + + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} + +static int +ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); } uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); uop_set_jump_dest(ir, jump_uop); - return 0; + } + return 0; +} +int +ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + } + return 0; } -static int ropJB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +static int +ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - int jump_uop; - int do_unroll = (CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + int jump_uop, jump_uop2 = -1; + int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero*/ - return 0; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + break; - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: + case FLAGS_UNKNOWN: + default: + if (do_unroll) { uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} -static int ropJNB_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = (!CF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero*/ - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - return 0; - - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JNB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JB_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} - -static int ropJE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - if (ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - } - return 0; -} -int ropJNE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - if (!ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)) - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - if (!codegen_flags_changed || !flags_res_valid()) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - } - return 0; -} - -static int ropJBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = ((CF_SET() || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero, so test zero only*/ - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - break; - - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - break; - } - if (do_unroll) - { - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 1; - } - else - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; - } -} -static int ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: case FLAGS_ZN16: case FLAGS_ZN32: - /*Carry is always zero, so test zero only*/ - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - break; - - case FLAGS_SUB8: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: - if (do_unroll) - jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - break; - } - if (do_unroll) - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 0; - } -} - -static int ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - break; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - break; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} -static int ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - break; - - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - break; - - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); - if (do_unroll) - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - break; - } - uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} - -static int ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; -} -static int ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - - uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; -} - -static int ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - /*V flag is always clear. Condition is true if N is set*/ - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - break; - case FLAGS_ZN16: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - break; - case FLAGS_ZN32: - if (do_unroll) - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - if (do_unroll) - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - else - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - break; - } - if (do_unroll) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} -static int ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop; - int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - /*V flag is always clear. Condition is true if N is set*/ - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); - break; - case FLAGS_ZN16: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); - break; - case FLAGS_ZN32: - if (do_unroll) - jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); - else - jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); - break; - - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - if (do_unroll) - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - else - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - break; - } - if (do_unroll) - uop_MOV_IMM(ir, IREG_pc, next_pc); - else - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return do_unroll ? 1 : 0; -} - -static int ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - } - break; - } - if (do_unroll) - { - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 1; - } - else - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 0; - } -} -static int ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) -{ - int jump_uop, jump_uop2 = -1; - int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); - - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_SUB8: case FLAGS_DEC8: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); - break; - case FLAGS_SUB16: case FLAGS_DEC16: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); - break; - case FLAGS_SUB32: case FLAGS_DEC32: - if (do_unroll) - jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - else - jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); - break; - - case FLAGS_UNKNOWN: - default: - if (do_unroll) - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); - } - else - { - uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); - uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); - jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); - } - break; - } - if (do_unroll) - { - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - uop_MOV_IMM(ir, IREG_pc, next_pc); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - return 1; - } - else - { - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - if (jump_uop2 != -1) - uop_set_jump_dest(ir, jump_uop2); - return 0; - } -} - -#define ropJ(cond) \ -uint32_t ropJ ## cond ## _8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); \ - uint32_t dest_addr = op_pc + 1 + offset; \ - int ret; \ - \ - if (!(op_32 & 0x100)) \ - dest_addr &= 0xffff; \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+1); \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - return ret ? dest_addr : (op_pc+1); \ -} \ -uint32_t ropJ ## cond ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); \ - uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ - int ret; \ - \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+2); \ - \ - codegen_mark_code_present(block, cs+op_pc, 2); \ - return ret ? dest_addr : (op_pc+2); \ -} \ -uint32_t ropJ ## cond ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - uint32_t dest_addr = op_pc + 4 + offset; \ - int ret; \ - \ - ret = ropJ ## cond ## _common(block, ir, dest_addr, op_pc+4); \ - \ - codegen_mark_code_present(block, cs+op_pc, 4); \ - return ret ? dest_addr : (op_pc+4); \ -} - -ropJ(O) -ropJ(NO) -ropJ(B) -ropJ(NB) -ropJ(E) -ropJ(NE) -ropJ(BE) -ropJ(NBE) -ropJ(S) -ropJ(NS) -ropJ(P) -ropJ(NP) -ropJ(L) -ropJ(NL) -ropJ(LE) -ropJ(NLE) - - -uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (op_32 & 0x200) - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); - else - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; -} - -uint32_t ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - uint32_t ret_addr; - int jump_uop; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc+1, dest_addr)) - { - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); - } - uop_MOV_IMM(ir, IREG_pc, op_pc+1); - ret_addr = dest_addr; - CPU_BLOCK_END(); - } - else - { - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - uop_MOV_IMM(ir, IREG_pc, dest_addr); - ret_addr = op_pc+1; - } - uop_JMP(ir, codegen_exit_rout); - uop_set_jump_dest(ir, jump_uop); - - codegen_mark_code_present(block, cs+op_pc, 1); - return ret_addr; -} - -uint32_t ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop, jump_uop2; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - if (!codegen_flags_changed || !flags_res_valid()) - { + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); - jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); - } + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } + break; + } + if (do_unroll) { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } else { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); - uop_NOP_BARRIER(ir); uop_set_jump_dest(ir, jump_uop); - uop_set_jump_dest(ir, jump_uop2); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; + return 0; + } } -uint32_t ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static int +ropJNBE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc + 1 + offset; - int jump_uop, jump_uop2; + int jump_uop, jump_uop2 = -1; + int do_unroll = ((!CF_SET() && !ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + /*Carry is always zero, so test zero only*/ + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + break; - if (op_32 & 0x200) - { - uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); - } - else - { - uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); - } - if (!codegen_flags_changed || !flags_res_valid()) - { + case FLAGS_SUB8: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + if (do_unroll) + jump_uop = uop_CMP_JNBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JBE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, CF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); - } - else - { - jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); - } + } + break; + } + if (do_unroll) { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { uop_MOV_IMM(ir, IREG_pc, dest_addr); uop_JMP(ir, codegen_exit_rout); - uop_NOP_BARRIER(ir); uop_set_jump_dest(ir, jump_uop); - uop_set_jump_dest(ir, jump_uop2); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc+1; + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } +} + +static int +ropJS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} +static int +ropJNS_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = (!NF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET); + if (do_unroll) + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + break; + } + uop_MOV_IMM(ir, IREG_pc, do_unroll ? next_pc : dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} + +static int +ropJP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; +} +static int +ropJNP_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + + uop_CALL_FUNC_RESULT(ir, IREG_temp0, PF_SET); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; +} + +static int +ropJL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + if (do_unroll) + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + if (do_unroll) + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} +static int +ropJNL_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop; + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + /*V flag is always clear. Condition is true if N is set*/ + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_B); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_B); + break; + case FLAGS_ZN16: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res_W); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res_W); + break; + case FLAGS_ZN32: + if (do_unroll) + jump_uop = uop_TEST_JNS_DEST(ir, IREG_flags_res); + else + jump_uop = uop_TEST_JS_DEST(ir, IREG_flags_res); + break; + + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JNL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JL_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + if (do_unroll) + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + else + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + break; + } + if (do_unroll) + uop_MOV_IMM(ir, IREG_pc, next_pc); + else + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return do_unroll ? 1 : 0; +} + +static int +ropJLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop, jump_uop2 = -1; + int do_unroll = (((NF_SET() ? 1 : 0) != (VF_SET() ? 1 : 0) || ZF_SET()) && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } + break; + } + if (do_unroll) { + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 1; + } else { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 0; + } +} +static int +ropJNLE_common(codeblock_t *block, ir_data_t *ir, uint32_t dest_addr, uint32_t next_pc) +{ + int jump_uop, jump_uop2 = -1; + int do_unroll = ((NF_SET() ? 1 : 0) == (VF_SET() ? 1 : 0) && !ZF_SET() && codegen_can_unroll(block, ir, next_pc, dest_addr)); + + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_SUB8: + case FLAGS_DEC8: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_B, IREG_flags_op2_B); + break; + case FLAGS_SUB16: + case FLAGS_DEC16: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1_W, IREG_flags_op2_W); + break; + case FLAGS_SUB32: + case FLAGS_DEC32: + if (do_unroll) + jump_uop = uop_CMP_JNLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + else + jump_uop = uop_CMP_JLE_DEST(ir, IREG_flags_op1, IREG_flags_op2); + break; + + case FLAGS_UNKNOWN: + default: + if (do_unroll) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JZ_DEST(ir, IREG_temp0, IREG_temp1); + } else { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + uop_CALL_FUNC_RESULT(ir, IREG_temp0, NF_SET_01); + uop_CALL_FUNC_RESULT(ir, IREG_temp1, VF_SET_01); + jump_uop = uop_CMP_JNZ_DEST(ir, IREG_temp0, IREG_temp1); + } + break; + } + if (do_unroll) { + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + uop_MOV_IMM(ir, IREG_pc, next_pc); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + return 1; + } else { + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + if (jump_uop2 != -1) + uop_set_jump_dest(ir, jump_uop2); + return 0; + } +} + +#define ropJ(cond) \ + uint32_t ropJ##cond##_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); \ + uint32_t dest_addr = op_pc + 1 + offset; \ + int ret; \ + \ + if (!(op_32 & 0x100)) \ + dest_addr &= 0xffff; \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 1); \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + return ret ? dest_addr : (op_pc + 1); \ + } \ + uint32_t ropJ##cond##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); \ + uint32_t dest_addr = (op_pc + 2 + offset) & 0xffff; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 2); \ + \ + codegen_mark_code_present(block, cs + op_pc, 2); \ + return ret ? dest_addr : (op_pc + 2); \ + } \ + uint32_t ropJ##cond##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + uint32_t dest_addr = op_pc + 4 + offset; \ + int ret; \ + \ + ret = ropJ##cond##_common(block, ir, dest_addr, op_pc + 4); \ + \ + codegen_mark_code_present(block, cs + op_pc, 4); \ + return ret ? dest_addr : (op_pc + 4); \ + } + +ropJ(O) + ropJ(NO) + ropJ(B) + ropJ(NB) + ropJ(E) + ropJ(NE) + ropJ(BE) + ropJ(NBE) + ropJ(S) + ropJ(NS) + ropJ(P) + ropJ(NP) + ropJ(L) + ropJ(NL) + ropJ(LE) + ropJ(NLE) + + uint32_t ropJCXZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (op_32 & 0x200) + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + else + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} + +uint32_t +ropLOOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + uint32_t ret_addr; + int jump_uop; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (((op_32 & 0x200) ? ECX : CX) != 1 && codegen_can_unroll(block, ir, op_pc + 1, dest_addr)) { + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JNZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, op_pc + 1); + ret_addr = dest_addr; + CPU_BLOCK_END(); + } else { + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + ret_addr = op_pc + 1; + } + uop_JMP(ir, codegen_exit_rout); + uop_set_jump_dest(ir, jump_uop); + + codegen_mark_code_present(block, cs + op_pc, 1); + return ret_addr; +} + +uint32_t +ropLOOPE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop, jump_uop2; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropLOOPNE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + int jump_uop, jump_uop2; + + if (!(op_32 & 0x100)) + dest_addr &= 0xffff; + + if (op_32 & 0x200) { + uop_SUB_IMM(ir, IREG_ECX, IREG_ECX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_ECX, 0); + } else { + uop_SUB_IMM(ir, IREG_CX, IREG_CX, 1); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_CX, 0); + } + if (!codegen_flags_changed || !flags_res_valid()) { + uop_CALL_FUNC_RESULT(ir, IREG_temp0, ZF_SET); + jump_uop2 = uop_CMP_IMM_JNZ_DEST(ir, IREG_temp0, 0); + } else { + jump_uop2 = uop_CMP_IMM_JZ_DEST(ir, IREG_flags_res, 0); + } + uop_MOV_IMM(ir, IREG_pc, dest_addr); + uop_JMP(ir, codegen_exit_rout); + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + uop_set_jump_dest(ir, jump_uop2); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_fpu_arith.c b/src/codegen_new/codegen_ops_fpu_arith.c index 598f63b80..e9739f830 100644 --- a/src/codegen_new/codegen_ops_fpu_arith.c +++ b/src/codegen_new/codegen_ops_fpu_arith.c @@ -14,562 +14,588 @@ #include "codegen_ops_fpu_arith.h" #include "codegen_ops_helpers.h" -uint32_t ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFADD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFADDr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFADDP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FADD(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } -uint32_t ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP2(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP2(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIV(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFDIVRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FDIV(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFMUL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFMULr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFMULP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FMUL(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUB(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_ST(src_reg)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(0), IREG_ST(src_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBRr(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSUBRP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FSUB(ir, IREG_ST(dest_reg), IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV_IMM(ir, IREG_tag(dest_reg), TAG_VALID); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFUCOM(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } -uint32_t ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFUCOMP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(src_reg)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFUCOMPP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - fpu_POP2(block, ir); + uop_FP_ENTER(ir); + uop_FCOM(ir, IREG_temp0_W, IREG_ST(0), IREG_ST(1)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + fpu_POP2(block, ir); - return op_pc; + return op_pc; } -#define ropF_arith_mem(name, load_uop) \ -uint32_t ropFADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - if ((cpu_state.npxc >> 10) & 3) \ - return 0; \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFCOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFCOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFSUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFSUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} +#define ropF_arith_mem(name, load_uop) \ + uint32_t ropFADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + if ((cpu_state.npxc >> 10) & 3) \ + return 0; \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFCOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFSUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + load_uop(ir, IREG_temp0_D, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } ropF_arith_mem(s, uop_MEM_LOAD_SINGLE) -ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) + ropF_arith_mem(d, uop_MEM_LOAD_DOUBLE) -#define ropFI_arith_mem(name, temp_reg) \ -uint32_t ropFIADD ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFICOM ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFICOMP ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); \ - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ - fpu_POP(block, ir); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIDIV ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIDIVR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFIMUL ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFISUB ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} \ -uint32_t ropFISUBR ## name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc)\ -{ \ - x86seg *target_seg; \ - \ - uop_FP_ENTER(ir); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - op_pc--; \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ - uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ - \ - return op_pc+1; \ -} +#define ropFI_arith_mem(name, temp_reg) \ + uint32_t ropFIADD##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FADD(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOM##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFICOMP##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FCOM(ir, IREG_temp1_W, IREG_ST(0), IREG_temp0_D); \ + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); \ + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp1_W); \ + fpu_POP(block, ir); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIV##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIDIVR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FDIV(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFIMUL##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FMUL(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUB##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_ST(0), IREG_temp0_D); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } \ + uint32_t ropFISUBR##name(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg; \ + \ + uop_FP_ENTER(ir); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + op_pc--; \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, temp_reg, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MOV_DOUBLE_INT(ir, IREG_temp0_D, temp_reg); \ + uop_FSUB(ir, IREG_ST(0), IREG_temp0_D, IREG_ST(0)); \ + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); \ + \ + return op_pc + 1; \ + } -ropFI_arith_mem(l, IREG_temp0) -ropFI_arith_mem(w, IREG_temp0_W) + ropFI_arith_mem(l, IREG_temp0) + ropFI_arith_mem(w, IREG_temp0_W) - -uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + uint32_t ropFABS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FABS(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FABS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFCHS(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FCHS(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSQRT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); + uop_FP_ENTER(ir); + uop_FSQRT(ir, IREG_ST(0), IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_VALID); - return op_pc; + return op_pc; } -uint32_t ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFTST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); - uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0|C2|C3)); - uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); + uop_FP_ENTER(ir); + uop_FTST(ir, IREG_temp0_W, IREG_ST(0)); + uop_AND_IMM(ir, IREG_NPXS, IREG_NPXS, ~(C0 | C2 | C3)); + uop_OR(ir, IREG_NPXS, IREG_NPXS, IREG_temp0_W); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_ops_fpu_constant.c b/src/codegen_new/codegen_ops_fpu_constant.c index fc59ae784..89c138637 100644 --- a/src/codegen_new/codegen_ops_fpu_constant.c +++ b/src/codegen_new/codegen_ops_fpu_constant.c @@ -14,23 +14,25 @@ #include "codegen_ops_fpu_constant.h" #include "codegen_ops_helpers.h" -uint32_t ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLD1(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_temp0, 1); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 1); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLDZ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_temp0, 0); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_temp0, 0); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_ops_fpu_loadstore.c b/src/codegen_new/codegen_ops_fpu_loadstore.c index 349d10de7..06709913d 100644 --- a/src/codegen_new/codegen_ops_fpu_loadstore.c +++ b/src/codegen_new/codegen_ops_fpu_loadstore.c @@ -14,221 +14,234 @@ #include "codegen_ops_fpu_arith.h" #include "codegen_ops_helpers.h" -uint32_t ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLDs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_SINGLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLDd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_DOUBLE(ir, IREG_ST(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTPs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_SINGLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTPd(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_DOUBLE(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_ST(0)); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } - -uint32_t ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFILDw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFILDl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFILDq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); - uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_ST_i64(-1), ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOV_DOUBLE_INT(ir, IREG_ST(-1), IREG_ST_i64(-1)); + uop_MOV_IMM(ir, IREG_tag(-1), TAG_VALID | TAG_UINT64); + fpu_PUSH(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTPw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0_W, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTPl(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE(ir, IREG_temp0, IREG_ST(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFISTPq(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); - uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MOV_INT_DOUBLE_64(ir, IREG_temp0_Q, IREG_ST(0), IREG_ST_i64(0), IREG_tag(0)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_Q); + uop_MOV_IMM(ir, IREG_tag(0), TAG_EMPTY); + fpu_POP(block, ir); - return op_pc+1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_fpu_misc.c b/src/codegen_new/codegen_ops_fpu_misc.c index cfe2ff698..cca9f4e4f 100644 --- a/src/codegen_new/codegen_ops_fpu_misc.c +++ b/src/codegen_new/codegen_ops_fpu_misc.c @@ -14,101 +14,109 @@ #include "codegen_ops_fpu_misc.h" #include "codegen_ops_helpers.h" -uint32_t ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFFREE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_tag(dest_reg), TAG_EMPTY); - return op_pc; + return op_pc; } -uint32_t ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = fetchdat & 7; + int src_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); - uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); - uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); - fpu_PUSH(block, ir); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(-1), IREG_ST(src_reg)); + uop_MOV(ir, IREG_ST_i64(-1), IREG_ST_i64(src_reg)); + uop_MOV(ir, IREG_tag(-1), IREG_tag(src_reg)); + fpu_PUSH(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFST(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); - uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - return op_pc; + return op_pc; } -uint32_t ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); - uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); - fpu_POP(block, ir); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_ST(dest_reg), IREG_ST(0)); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_ST_i64(0)); + uop_MOV(ir, IREG_tag(dest_reg), IREG_tag(0)); + fpu_POP(block, ir); - return op_pc; + return op_pc; } -uint32_t ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTCW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXC); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTSW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg; + x86seg *target_seg; - uop_FP_ENTER(ir); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - op_pc--; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); + uop_FP_ENTER(ir); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + op_pc--; + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_NPXS); - return op_pc+1; + return op_pc + 1; } -uint32_t ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFSTSW_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_AX, IREG_NPXS); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_AX, IREG_NPXS); - return op_pc; + return op_pc; } -uint32_t ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFXCH(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = fetchdat & 7; + int dest_reg = fetchdat & 7; - uop_FP_ENTER(ir); - uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); - uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); - uop_MOV(ir, IREG_temp2, IREG_tag(0)); - uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); - uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); - uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); - uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); - uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); - uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); + uop_FP_ENTER(ir); + uop_MOV(ir, IREG_temp0_D, IREG_ST(0)); + uop_MOV(ir, IREG_temp1_Q, IREG_ST_i64(0)); + uop_MOV(ir, IREG_temp2, IREG_tag(0)); + uop_MOV(ir, IREG_ST(0), IREG_ST(dest_reg)); + uop_MOV(ir, IREG_ST_i64(0), IREG_ST_i64(dest_reg)); + uop_MOV(ir, IREG_tag(0), IREG_tag(dest_reg)); + uop_MOV(ir, IREG_ST(dest_reg), IREG_temp0_D); + uop_MOV(ir, IREG_ST_i64(dest_reg), IREG_temp1_Q); + uop_MOV(ir, IREG_tag(dest_reg), IREG_temp2); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_ops_helpers.c b/src/codegen_new/codegen_ops_helpers.c index 9c2280f07..242cbb818 100644 --- a/src/codegen_new/codegen_ops_helpers.c +++ b/src/codegen_new/codegen_ops_helpers.c @@ -11,65 +11,64 @@ #include "codegen_reg.h" #include "codegen_ops_helpers.h" -void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +void +LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); - uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr+1)); - uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); - uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); + /*Word access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOVZX_REG_PTR_8(ir, IREG_temp3_W, get_ram_ptr(addr)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr + 1)); + uop_SHL_IMM(ir, IREG_temp3_W, IREG_temp3_W, 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3_W); } -void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +void +LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ - uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); - uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); - uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); - uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); - uop_OR(ir, dest_reg, dest_reg, IREG_temp3); + /*Dword access that crosses two pages. Perform reads from both pages, shift and combine*/ + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr & ~3)); + uop_MOV_REG_PTR(ir, IREG_temp3, get_ram_ptr((addr + 4) & ~3)); + uop_SHR_IMM(ir, dest_reg, dest_reg, (addr & 3) * 8); + uop_SHL_IMM(ir, IREG_temp3, IREG_temp3, (4 - (addr & 3)) * 8); + uop_OR(ir, dest_reg, dest_reg, IREG_temp3); } #define UNROLL_MAX_REG_REFERENCES 200 -#define UNROLL_MAX_UOPS 1000 -#define UNROLL_MAX_COUNT 10 -int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +#define UNROLL_MAX_UOPS 1000 +#define UNROLL_MAX_COUNT 10 +int +codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - int start; - int max_unroll; - int first_instruction; - int TOP = -1; + int start; + int max_unroll; + int first_instruction; + int TOP = -1; - /*Check that dest instruction was actually compiled into block*/ - start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); + /*Check that dest instruction was actually compiled into block*/ + start = codegen_get_instruction_uop(block, dest_addr, &first_instruction, &TOP); - /*Couldn't find any uOPs corresponding to the destination instruction*/ - if (start == -1) - { - /*Is instruction jumping to itself?*/ - if (dest_addr != cpu_state.oldpc) - { - return 0; - } - else - { - start = ir->wr_pos; - TOP = cpu_state.TOP; - } + /*Couldn't find any uOPs corresponding to the destination instruction*/ + if (start == -1) { + /*Is instruction jumping to itself?*/ + if (dest_addr != cpu_state.oldpc) { + return 0; + } else { + start = ir->wr_pos; + TOP = cpu_state.TOP; } + } - if (TOP != cpu_state.TOP) - return 0; + if (TOP != cpu_state.TOP) + return 0; - max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos-start)+6); - if ((max_version_refcount != 0) && (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))) - max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); - if (max_unroll > UNROLL_MAX_COUNT) - max_unroll = UNROLL_MAX_COUNT; - if (max_unroll <= 1) - return 0; + max_unroll = UNROLL_MAX_UOPS / ((ir->wr_pos - start) + 6); + if ((max_version_refcount != 0) && (max_unroll > (UNROLL_MAX_REG_REFERENCES / max_version_refcount))) + max_unroll = (UNROLL_MAX_REG_REFERENCES / max_version_refcount); + if (max_unroll > UNROLL_MAX_COUNT) + max_unroll = UNROLL_MAX_COUNT; + if (max_unroll <= 1) + return 0; - codegen_ir_set_unroll(max_unroll, start, first_instruction); + codegen_ir_set_unroll(max_unroll, start, first_instruction); - return 1; + return 1; } diff --git a/src/codegen_new/codegen_ops_helpers.h b/src/codegen_new/codegen_ops_helpers.h index 41ffe297f..5a8f1e1c7 100644 --- a/src/codegen_new/codegen_ops_helpers.h +++ b/src/codegen_new/codegen_ops_helpers.h @@ -1,126 +1,127 @@ #include "386_common.h" #include "codegen_backend.h" -static inline int LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) +static inline int +LOAD_SP_WITH_OFFSET(ir_data_t *ir, int offset) { - if (stack32) - { - if (offset) - { - uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset); - return IREG_eaaddr; - } - else - return IREG_ESP; - } - else - { - if (offset) - { - uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset); - uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W); - return IREG_eaaddr; - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - return IREG_eaaddr; - } + if (stack32) { + if (offset) { + uop_ADD_IMM(ir, IREG_eaaddr, IREG_ESP, offset); + return IREG_eaaddr; + } else + return IREG_ESP; + } else { + if (offset) { + uop_ADD_IMM(ir, IREG_eaaddr_W, IREG_SP, offset); + uop_MOVZX(ir, IREG_eaaddr, IREG_eaaddr_W); + return IREG_eaaddr; + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + return IREG_eaaddr; } + } } -static inline int LOAD_SP(ir_data_t *ir) +static inline int +LOAD_SP(ir_data_t *ir) { - return LOAD_SP_WITH_OFFSET(ir, 0); + return LOAD_SP_WITH_OFFSET(ir, 0); } -static inline void ADD_SP(ir_data_t *ir, int offset) +static inline void +ADD_SP(ir_data_t *ir, int offset) { - if (stack32) - uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset); - else - uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset); + if (stack32) + uop_ADD_IMM(ir, IREG_ESP, IREG_ESP, offset); + else + uop_ADD_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void SUB_SP(ir_data_t *ir, int offset) +static inline void +SUB_SP(ir_data_t *ir, int offset) { - if (stack32) - uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset); - else - uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); + if (stack32) + uop_SUB_IMM(ir, IREG_ESP, IREG_ESP, offset); + else + uop_SUB_IMM(ir, IREG_SP, IREG_SP, offset); } -static inline void fpu_POP(codeblock_t *block, ir_data_t *ir) +static inline void +fpu_POP(codeblock_t *block, ir_data_t *ir) { - if (block->flags & CODEBLOCK_STATIC_TOP) - uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1); - else - uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 1); + else + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void fpu_POP2(codeblock_t *block, ir_data_t *ir) +static inline void +fpu_POP2(codeblock_t *block, ir_data_t *ir) { - if (block->flags & CODEBLOCK_STATIC_TOP) - uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2); - else - uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP + 2); + else + uop_ADD_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 2); } -static inline void fpu_PUSH(codeblock_t *block, ir_data_t *ir) +static inline void +fpu_PUSH(codeblock_t *block, ir_data_t *ir) { - if (block->flags & CODEBLOCK_STATIC_TOP) - uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1); - else - uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); + if (block->flags & CODEBLOCK_STATIC_TOP) + uop_MOV_IMM(ir, IREG_FPU_TOP, cpu_state.TOP - 1); + else + uop_SUB_IMM(ir, IREG_FPU_TOP, IREG_FPU_TOP, 1); } -static inline void CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) +static inline void +CHECK_SEG_LIMITS(codeblock_t *block, ir_data_t *ir, x86seg *seg, int addr_reg, int end_offset) { - if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || - (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) - return; + if ((seg == &cpu_state.seg_ds && codegen_flat_ds && !(cpu_cur_status & CPU_STATUS_NOTFLATDS)) || (seg == &cpu_state.seg_ss && codegen_flat_ss && !(cpu_cur_status & CPU_STATUS_NOTFLATSS))) + return; - uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout); - if (end_offset) - { - uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset); - uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout); - } - else - uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); + uop_CMP_JB(ir, addr_reg, ireg_seg_limit_low(seg), codegen_gpf_rout); + if (end_offset) { + uop_ADD_IMM(ir, IREG_temp3, addr_reg, end_offset); + uop_CMP_JNBE(ir, IREG_temp3, ireg_seg_limit_high(seg), codegen_gpf_rout); + } else + uop_CMP_JNBE(ir, addr_reg, ireg_seg_limit_high(seg), codegen_gpf_rout); } -static inline void LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +static inline void +LOAD_IMMEDIATE_FROM_RAM_8(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); + uop_MOVZX_REG_PTR_8(ir, dest_reg, get_ram_ptr(addr)); } void LOAD_IMMEDIATE_FROM_RAM_16_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); -static inline void LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +static inline void +LOAD_IMMEDIATE_FROM_RAM_16(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - if ((addr & 0xfff) == 0xfff) - LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr); - else - uop_MOVZX_REG_PTR_16(ir, dest_reg, get_ram_ptr(addr)); + if ((addr & 0xfff) == 0xfff) + LOAD_IMMEDIATE_FROM_RAM_16_unaligned(block, ir, dest_reg, addr); + else + uop_MOVZX_REG_PTR_16(ir, dest_reg, get_ram_ptr(addr)); } void LOAD_IMMEDIATE_FROM_RAM_32_unaligned(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr); -static inline void LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) +static inline void +LOAD_IMMEDIATE_FROM_RAM_32(codeblock_t *block, ir_data_t *ir, int dest_reg, uint32_t addr) { - if ((addr & 0xfff) >= 0xffd) - LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr); - else - uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr)); + if ((addr & 0xfff) >= 0xffd) + LOAD_IMMEDIATE_FROM_RAM_32_unaligned(block, ir, dest_reg, addr); + else + uop_MOV_REG_PTR(ir, dest_reg, get_ram_ptr(addr)); } int codegen_can_unroll_full(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr); -static inline int codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) +static inline int +codegen_can_unroll(codeblock_t *block, ir_data_t *ir, uint32_t next_pc, uint32_t dest_addr) { - if (block->flags & CODEBLOCK_BYTE_MASK) - return 0; + if (block->flags & CODEBLOCK_BYTE_MASK) + return 0; - /*Is dest within block?*/ - if (dest_addr > next_pc) - return 0; - if ((cs+dest_addr) < block->pc) - return 0; + /*Is dest within block?*/ + if (dest_addr > next_pc) + return 0; + if ((cs + dest_addr) < block->pc) + return 0; - return codegen_can_unroll_full(block, ir, next_pc, dest_addr); + return codegen_can_unroll_full(block, ir, next_pc, dest_addr); } diff --git a/src/codegen_new/codegen_ops_jump.c b/src/codegen_new/codegen_ops_jump.c index f672b40ca..0bd4db24a 100644 --- a/src/codegen_new/codegen_ops_jump.c +++ b/src/codegen_new/codegen_ops_jump.c @@ -11,282 +11,281 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -uint32_t ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_r8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int8_t)fastreadb(cs + op_pc); - uint32_t dest_addr = op_pc+1+offset; - - if (!(op_32 & 0x100)) - dest_addr &= 0xffff; - - if (offset < 0) - codegen_can_unroll(block, ir, op_pc+1, dest_addr); - codegen_mark_code_present(block, cs+op_pc, 1); - return dest_addr; -} -uint32_t ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); - uint32_t dest_addr = op_pc+2+offset; + uint32_t offset = (int32_t) (int8_t) fastreadb(cs + op_pc); + uint32_t dest_addr = op_pc + 1 + offset; + if (!(op_32 & 0x100)) dest_addr &= 0xffff; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc+1, dest_addr); - codegen_mark_code_present(block, cs+op_pc, 2); - return dest_addr; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 1); + return dest_addr; } -uint32_t ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = fastreadl(cs + op_pc); - uint32_t dest_addr = op_pc+4+offset; + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); + uint32_t dest_addr = op_pc + 2 + offset; - if (offset < 0) - codegen_can_unroll(block, ir, op_pc+1, dest_addr); - codegen_mark_code_present(block, cs+op_pc, 4); - return dest_addr; + dest_addr &= 0xffff; + + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 2); + return dest_addr; } - -uint32_t ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t new_pc = fastreadw(cs + op_pc); - uint16_t new_cs = fastreadw(cs + op_pc + 2); + uint32_t offset = fastreadl(cs + op_pc); + uint32_t dest_addr = op_pc + 4 + offset; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_pc, new_pc); - uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); - uop_CALL_FUNC(ir, loadcsjmp); - - codegen_mark_code_present(block, cs+op_pc, 4); - return -1; + if (offset < 0) + codegen_can_unroll(block, ir, op_pc + 1, dest_addr); + codegen_mark_code_present(block, cs + op_pc, 4); + return dest_addr; } -uint32_t ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropJMP_far_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t new_pc = fastreadl(cs + op_pc); - uint16_t new_cs = fastreadw(cs + op_pc + 4); + uint16_t new_pc = fastreadw(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 2); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_pc, new_pc); - uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); - uop_CALL_FUNC(ir, loadcsjmp); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); - codegen_mark_code_present(block, cs+op_pc, 6); - return -1; + codegen_mark_code_present(block, cs + op_pc, 4); + return -1; } - -uint32_t ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropJMP_far_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = (int32_t)(int16_t)fastreadw(cs + op_pc); - uint16_t ret_addr = op_pc + 2; - uint16_t dest_addr = ret_addr + offset; - int sp_reg; + uint32_t new_pc = fastreadl(cs + op_pc); + uint16_t new_cs = fastreadw(cs + op_pc + 4); - dest_addr &= 0xffff; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_pc, new_pc); + uop_LOAD_FUNC_ARG_IMM(ir, 0, new_cs); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 4); + uop_CALL_FUNC(ir, loadcsjmp); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); - SUB_SP(ir, 2); - uop_MOV_IMM(ir, IREG_pc, dest_addr); - - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 6); + return -1; } -uint32_t ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropCALL_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint32_t offset = fastreadl(cs + op_pc); - uint32_t ret_addr = op_pc + 4; - uint32_t dest_addr = ret_addr + offset; - int sp_reg; + uint32_t offset = (int32_t) (int16_t) fastreadw(cs + op_pc); + uint16_t ret_addr = op_pc + 2; + uint16_t dest_addr = ret_addr + offset; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); - SUB_SP(ir, 4); - uop_MOV_IMM(ir, IREG_pc, dest_addr); + dest_addr &= 0xffff; - codegen_mark_code_present(block, cs+op_pc, 4); - return -1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_pc, dest_addr); + + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } - -uint32_t ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCALL_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uint32_t offset = fastreadl(cs + op_pc); + uint32_t ret_addr = op_pc + 4; + uint32_t dest_addr = ret_addr + offset; + int sp_reg; - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 2); - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, ret_addr); + SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_pc, dest_addr); - return -1; + codegen_mark_code_present(block, cs + op_pc, 4); + return -1; } -uint32_t ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRET_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 4); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - return -1; + return -1; } - -uint32_t ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropRET_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 2+offset); - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + return -1; } -uint32_t ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRET_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset = fastreadw(cs + op_pc); + uint16_t offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); - } - ADD_SP(ir, 4+offset); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 2 + offset); + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } - -uint32_t ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropRET_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + uint16_t offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); - } - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 4); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_pc, IREG_SS_base, IREG_eaaddr); + } + ADD_SP(ir, 4 + offset); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } -uint32_t ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRETF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); - } - uop_MOV(ir, IREG_pc, IREG_temp0); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 8); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4); - return -1; + return -1; } - -uint32_t ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropRETF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); - } - uop_MOVZX(ir, IREG_pc, IREG_temp0_W); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 4+offset); - - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + return -1; } -uint32_t ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropRETF_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t offset; + uint16_t offset; - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) - return 0; + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; - offset = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - { - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); - } - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); - } - uop_MOV(ir, IREG_pc, IREG_temp0); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_CALL_FUNC(ir, loadcs); - ADD_SP(ir, 8+offset); + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 2); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 2); + } + uop_MOVZX(ir, IREG_pc, IREG_temp0_W); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 4 + offset); - codegen_mark_code_present(block, cs+op_pc, 2); - return -1; + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; +} +uint32_t +ropRETF_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t offset; + + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) + return 0; + + offset = fastreadw(cs + op_pc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) { + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_ESP, 4); + } else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, IREG_SS_base, IREG_eaaddr, 4); + } + uop_MOV(ir, IREG_pc, IREG_temp0); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_CALL_FUNC(ir, loadcs); + ADD_SP(ir, 8 + offset); + + codegen_mark_code_present(block, cs + op_pc, 2); + return -1; } diff --git a/src/codegen_new/codegen_ops_logic.c b/src/codegen_new/codegen_ops_logic.c index dd02bd3f9..6db452a45 100644 --- a/src/codegen_new/codegen_ops_logic.c +++ b/src/codegen_new/codegen_ops_logic.c @@ -12,796 +12,754 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_logic.h" -uint32_t ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_AND_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_AND_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_AND_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - return op_pc + 4; + codegen_flags_changed = 1; + return op_pc + 4; } -uint32_t ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropAND_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropAND_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - uop_AND(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_OR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_OR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_OR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_OR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_OR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, dest_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, dest_reg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_OR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_AND(ir, IREG_flags_res, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_AND_IMM(ir, IREG_flags_res, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_B, IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res_W, IREG_16(dest_reg), IREG_temp0_W); + } - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropTEST_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_flags_res, IREG_32(dest_reg), IREG_temp0); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_AL_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm_data = fastreadb(cs + op_pc); + uint8_t imm_data = fastreadb(cs + op_pc); - uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - uop_MOVZX(ir, IREG_flags_res, IREG_AL); + uop_XOR_IMM(ir, IREG_AL, IREG_AL, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_AL); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_AX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm_data = fastreadw(cs + op_pc); + uint16_t imm_data = fastreadw(cs + op_pc); - uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - uop_MOVZX(ir, IREG_flags_res, IREG_AX); + uop_XOR_IMM(ir, IREG_AX, IREG_AX, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_AX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_EAX_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); - uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); - } - else - { - fetchdat = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); - } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_temp0, cs + op_pc); + uop_XOR(ir, IREG_EAX, IREG_EAX, IREG_temp0); + } else { + fetchdat = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); + uop_XOR_IMM(ir, IREG_EAX, IREG_EAX, fetchdat); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, IREG_EAX); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, IREG_EAX); - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; } -uint32_t ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_b_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp0_B); + } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_b_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_8(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0_B, IREG_temp0_B, IREG_8(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_w_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp0_W); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + x86seg *target_seg; - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + } + + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_w_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_16(src_reg)); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); + } - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0_W, IREG_temp0_W, IREG_16(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + uop_MOV(ir, IREG_flags_res, dest_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - return op_pc + 1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropXOR_l_rm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - uop_MOV(ir, IREG_flags_res, dest_reg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + } - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropXOR_l_rmw(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_XOR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_32(src_reg)); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_temp0, IREG_temp0, IREG_32(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - } - - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - return op_pc + 1; + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_misc.c b/src/codegen_new/codegen_ops_misc.c index adb478d13..7f7613dbf 100644 --- a/src/codegen_new/codegen_ops_misc.c +++ b/src/codegen_new/codegen_ops_misc.c @@ -12,603 +12,591 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_misc.h" -uint32_t ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); - - return op_pc + 1; -} -uint32_t ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - if ((fetchdat & 0xc0) == 0xc0) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); - - return op_pc + 1; -} - -uint32_t ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - uint8_t imm_data; - int reg; - - if (fetchdat & 0x20) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_8(fetchdat & 7); - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0_B; - } - - switch (fetchdat & 0x38) - { - case 0x00: case 0x08: /*TEST*/ - imm_data = fastreadb(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc+2; - - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - - codegen_flags_changed = 1; - return op_pc+1; - - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1_B, 0); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - uop_MOV(ir, reg, IREG_temp1_B); - } - else - { - uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); - uop_MOV_IMM(ir, IREG_flags_op1, 0); - - codegen_flags_changed = 1; - return op_pc+1; - } + if ((fetchdat & 0xc0) == 0xc0) return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_16(dest_reg), IREG_eaaddr_W); + + return op_pc + 1; } -uint32_t ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint16_t imm_data; - int reg; + int dest_reg = (fetchdat >> 3) & 7; - if (fetchdat & 0x20) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_16(fetchdat & 7); - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0_W; - } - - switch (fetchdat & 0x38) - { - case 0x00: case 0x08: /*TEST*/ - imm_data = fastreadw(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); - uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 2); - return op_pc+3; - - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xffff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - - codegen_flags_changed = 1; - return op_pc+1; - - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1_W, 0); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV(ir, reg, IREG_temp1_W); - } - else - { - uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); - uop_MOV_IMM(ir, IREG_flags_op1, 0); - - codegen_flags_changed = 1; - return op_pc+1; - } + if ((fetchdat & 0xc0) == 0xc0) return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + uop_MOV(ir, IREG_32(dest_reg), IREG_eaaddr); + + return op_pc + 1; } -uint32_t ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropF6(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - uint32_t imm_data; - int reg; + x86seg *target_seg = NULL; + uint8_t imm_data; + int reg; - if (fetchdat & 0x20) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - reg = IREG_32(fetchdat & 7); - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - reg = IREG_temp0; - } - - switch (fetchdat & 0x38) - { - case 0x00: case 0x08: /*TEST*/ - imm_data = fastreadl(cs + op_pc + 1); - - uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); - - codegen_flags_changed = 1; - codegen_mark_code_present(block, cs+op_pc+1, 4); - return op_pc+5; - - case 0x10: /*NOT*/ - uop_XOR_IMM(ir, reg, reg, 0xffffffff); - if ((fetchdat & 0xc0) != 0xc0) - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - - codegen_flags_changed = 1; - return op_pc+1; - - case 0x18: /*NEG*/ - uop_MOV_IMM(ir, IREG_temp1, 0); - - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_flags_op2, reg); - uop_SUB(ir, IREG_temp1, IREG_temp1, reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV(ir, reg, IREG_temp1); - } - else - { - uop_SUB(ir, IREG_temp1, IREG_temp1, reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op2, IREG_temp0); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - } - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); - uop_MOV_IMM(ir, IREG_flags_op1, 0); - - codegen_flags_changed = 1; - return op_pc+1; - } + if (fetchdat & 0x20) return 0; -} -static void rebuild_c(ir_data_t *ir) -{ - int needs_rebuild = 1; - - if (codegen_flags_changed) - { - switch (cpu_state.flags_op) - { - case FLAGS_INC8: case FLAGS_INC16: case FLAGS_INC32: - case FLAGS_DEC8: case FLAGS_DEC16: case FLAGS_DEC32: - needs_rebuild = 0; - break; - } - } - - if (needs_rebuild) - { - uop_CALL_FUNC(ir, flags_rebuild_c); - } -} - -uint32_t ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg, sp_reg; - - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if ((fetchdat & 0x38) == 0x28) - return 0; - src_reg = IREG_16(fetchdat & 7); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_8(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if (!(fetchdat & 0x30)) /*INC/DEC*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0_W; - } + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_B; + } - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadb(cs + op_pc + 1); - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_ADD_IMM(ir, src_reg, src_reg, 1); - uop_MOVZX(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - } - else - { - uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); - } - return op_pc+1; + uop_AND_IMM(ir, IREG_flags_res_B, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN8); - case 0x08: /*DEC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_SUB_IMM(ir, src_reg, src_reg, 1); - uop_MOVZX(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - } - else - { - uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, src_reg); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); - } - return op_pc+1; + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - case 0x10: /*CALL*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); - SUB_SP(ir, 2); - uop_MOVZX(ir, IREG_pc, src_reg); - return -1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x20: /*JMP*/ - uop_MOVZX(ir, IREG_pc, src_reg); - return -1; + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_B, 0); - case 0x28: /*JMP far*/ - uop_MOVZX(ir, IREG_pc, src_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); - uop_CALL_FUNC(ir, loadcsjmp); - return -1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + uop_MOV(ir, reg, IREG_temp1_B); + } else { + uop_SUB(ir, IREG_temp1_B, IREG_temp1_B, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_B); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB8); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - case 0x30: /*PUSH*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); - SUB_SP(ir, 2); - return op_pc+1; - } - return 0; + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } - -uint32_t ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropF7_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - x86seg *target_seg = NULL; - int src_reg, sp_reg; + x86seg *target_seg = NULL; + uint16_t imm_data; + int reg; - if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) - return 0; + if (fetchdat & 0x20) + return 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if ((fetchdat & 0x38) == 0x28) - return 0; - src_reg = IREG_32(fetchdat & 7); - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_16(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - if (!(fetchdat & 0x30)) /*INC/DEC*/ - codegen_check_seg_write(block, ir, target_seg); - else - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0; - } + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0_W; + } - switch (fetchdat & 0x38) - { - case 0x00: /*INC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadw(cs + op_pc + 1); - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_ADD_IMM(ir, src_reg, src_reg, 1); - uop_MOV(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - } - else - { - uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); - } - return op_pc+1; + uop_AND_IMM(ir, IREG_flags_res_W, reg, imm_data); + uop_MOVZX(ir, IREG_flags_res, IREG_flags_res_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN16); - case 0x08: /*DEC*/ - rebuild_c(ir); - codegen_flags_changed = 1; + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_SUB_IMM(ir, src_reg, src_reg, 1); - uop_MOV(ir, IREG_flags_res, src_reg); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - } - else - { - uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, src_reg); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, 1); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); - } - return op_pc+1; + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); - case 0x10: /*CALL*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); - SUB_SP(ir, 4); - uop_MOV(ir, IREG_pc, src_reg); - return -1; + codegen_flags_changed = 1; + return op_pc + 1; - case 0x20: /*JMP*/ - uop_MOV(ir, IREG_pc, src_reg); - return -1; + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1_W, 0); - case 0x28: /*JMP far*/ - uop_MOV(ir, IREG_pc, src_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); - uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); - uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); - uop_CALL_FUNC(ir, loadcsjmp); - return -1; + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV(ir, reg, IREG_temp1_W); + } else { + uop_SUB(ir, IREG_temp1_W, IREG_temp1_W, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op2, IREG_temp0_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB16); + uop_MOV_IMM(ir, IREG_flags_op1, 0); - case 0x30: /*PUSH*/ - if ((fetchdat & 0xc0) == 0xc0) - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); - SUB_SP(ir, 4); - return op_pc+1; - } + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; +} +uint32_t +ropF7_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint32_t imm_data; + int reg; + + if (fetchdat & 0x20) return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) + reg = IREG_32(fetchdat & 7); + else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if ((fetchdat & 0x30) == 0x10) /*NEG/NOT*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + reg = IREG_temp0; + } + + switch (fetchdat & 0x38) { + case 0x00: + case 0x08: /*TEST*/ + imm_data = fastreadl(cs + op_pc + 1); + + uop_AND_IMM(ir, IREG_flags_res, reg, imm_data); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ZN32); + + codegen_flags_changed = 1; + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; + + case 0x10: /*NOT*/ + uop_XOR_IMM(ir, reg, reg, 0xffffffff); + if ((fetchdat & 0xc0) != 0xc0) + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg); + + codegen_flags_changed = 1; + return op_pc + 1; + + case 0x18: /*NEG*/ + uop_MOV_IMM(ir, IREG_temp1, 0); + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op2, reg); + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV(ir, reg, IREG_temp1); + } else { + uop_SUB(ir, IREG_temp1, IREG_temp1, reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op2, IREG_temp0); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + } + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SUB32); + uop_MOV_IMM(ir, IREG_flags_op1, 0); + + codegen_flags_changed = 1; + return op_pc + 1; + } + return 0; } -uint32_t ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static void +rebuild_c(ir_data_t *ir) { - return op_pc; + int needs_rebuild = 1; + + if (codegen_flags_changed) { + switch (cpu_state.flags_op) { + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + needs_rebuild = 0; + break; + } + } + + if (needs_rebuild) { + uop_CALL_FUNC(ir, flags_rebuild_c); + } } -uint32_t ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropFF_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOVSX(ir, IREG_AX, IREG_AL); + x86seg *target_seg = NULL; + int src_reg, sp_reg; - return op_pc; + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if ((fetchdat & 0x38) == 0x28) + return 0; + src_reg = IREG_16(fetchdat & 7); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } else { + uop_ADD_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC16); + } + return op_pc + 1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOVZX(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } else { + uop_SUB_IMM(ir, IREG_temp1_W, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, src_reg); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC16); + } + return op_pc + 1; + + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 2); + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; + + case 0x20: /*JMP*/ + uop_MOVZX(ir, IREG_pc, src_reg); + return -1; + + case 0x28: /*JMP far*/ + uop_MOVZX(ir, IREG_pc, src_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); + uop_CALL_FUNC(ir, loadcsjmp); + return -1; + + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 2); + return op_pc + 1; + } + return 0; } -uint32_t ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropFF_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); + x86seg *target_seg = NULL; + int src_reg, sp_reg; - return op_pc; + if ((fetchdat & 0x38) != 0x00 && (fetchdat & 0x38) != 0x08 && (fetchdat & 0x38) != 0x10 && (fetchdat & 0x38) != 0x20 && (fetchdat & 0x38) != 0x28 && (fetchdat & 0x38) != 0x30) + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if ((fetchdat & 0x38) == 0x28) + return 0; + src_reg = IREG_32(fetchdat & 7); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + if (!(fetchdat & 0x30)) /*INC/DEC*/ + codegen_check_seg_write(block, ir, target_seg); + else + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0; + } + + switch (fetchdat & 0x38) { + case 0x00: /*INC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_ADD_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } else { + uop_ADD_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_INC32); + } + return op_pc + 1; + + case 0x08: /*DEC*/ + rebuild_c(ir); + codegen_flags_changed = 1; + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_SUB_IMM(ir, src_reg, src_reg, 1); + uop_MOV(ir, IREG_flags_res, src_reg); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } else { + uop_SUB_IMM(ir, IREG_temp1, src_reg, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, src_reg); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, 1); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_DEC32); + } + return op_pc + 1; + + case 0x10: /*CALL*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, op_pc + 1); + SUB_SP(ir, 4); + uop_MOV(ir, IREG_pc, src_reg); + return -1; + + case 0x20: /*JMP*/ + uop_MOV(ir, IREG_pc, src_reg); + return -1; + + case 0x28: /*JMP far*/ + uop_MOV(ir, IREG_pc, src_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); + uop_LOAD_FUNC_ARG_REG(ir, 0, IREG_temp1_W); + uop_LOAD_FUNC_ARG_IMM(ir, 1, op_pc + 1); + uop_CALL_FUNC(ir, loadcsjmp); + return -1; + + case 0x30: /*PUSH*/ + if ((fetchdat & 0xc0) == 0xc0) + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, src_reg); + SUB_SP(ir, 4); + return op_pc + 1; + } + return 0; } -uint32_t ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropNOP(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); - - return op_pc; + return op_pc; } -uint32_t ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + +uint32_t +ropCBW(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOVSX(ir, IREG_EAX, IREG_AX); + uop_MOVSX(ir, IREG_AX, IREG_AL); - return op_pc; + return op_pc; +} +uint32_t +ropCDQ(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_SAR_IMM(ir, IREG_EDX, IREG_EAX, 31); + + return op_pc; +} +uint32_t +ropCWD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_SAR_IMM(ir, IREG_DX, IREG_AX, 15); + + return op_pc; +} +uint32_t +ropCWDE(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOVSX(ir, IREG_EAX, IREG_AX); + + return op_pc; } -#define ropLxS(name, seg) \ -uint32_t rop ## name ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ -} \ -uint32_t rop ## name ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - x86seg *target_seg = NULL; \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - if ((fetchdat & 0xc0) == 0xc0) \ - return 0; \ - \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ - uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ - uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ - \ - if (seg == &cpu_state.seg_ss) \ - CPU_BLOCK_END(); \ - \ - return op_pc + 1; \ -} +#define ropLxS(name, seg) \ + uint32_t rop##name##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 2); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_16(dest_reg), IREG_temp0_W); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } \ + uint32_t rop##name##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + x86seg *target_seg = NULL; \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + if ((fetchdat & 0xc0) == 0xc0) \ + return 0; \ + \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_MEM_LOAD_REG_OFFSET(ir, IREG_temp1_W, ireg_seg_base(target_seg), IREG_eaaddr, 4); \ + uop_LOAD_SEG(ir, seg, IREG_temp1_W); \ + uop_MOV(ir, IREG_32(dest_reg), IREG_temp0); \ + \ + if (seg == &cpu_state.seg_ss) \ + CPU_BLOCK_END(); \ + \ + return op_pc + 1; \ + } ropLxS(LDS, &cpu_state.seg_ds) -ropLxS(LES, &cpu_state.seg_es) -ropLxS(LFS, &cpu_state.seg_fs) -ropLxS(LGS, &cpu_state.seg_gs) -ropLxS(LSS, &cpu_state.seg_ss) + ropLxS(LES, &cpu_state.seg_es) + ropLxS(LFS, &cpu_state.seg_fs) + ropLxS(LGS, &cpu_state.seg_gs) + ropLxS(LSS, &cpu_state.seg_ss) -uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) + uint32_t ropCLC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~C_FLAG); + return op_pc; } -uint32_t ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCMC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_XOR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; } -uint32_t ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSTC(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_CALL_FUNC(ir, flags_rebuild); - uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); - return op_pc; + uop_CALL_FUNC(ir, flags_rebuild); + uop_OR_IMM(ir, IREG_flags, IREG_flags, C_FLAG); + return op_pc; } -uint32_t ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCLD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); - return op_pc; + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~D_FLAG); + return op_pc; } -uint32_t ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSTD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); - return op_pc; + uop_OR_IMM(ir, IREG_flags, IREG_flags, D_FLAG); + return op_pc; } -uint32_t ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropCLI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; - uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); - return op_pc; + uop_AND_IMM(ir, IREG_flags, IREG_flags, ~I_FLAG); + return op_pc; } -uint32_t ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropSTI(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) - return 0; + if (!IOPLp && (cr4 & (CR4_VME | CR4_PVI))) + return 0; - uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); - return op_pc; + uop_OR_IMM(ir, IREG_flags, IREG_flags, I_FLAG); + return op_pc; } diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index 66124ca5e..67e73883e 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -13,31 +13,28 @@ #include "codegen_ops_mmx_arith.h" #include "codegen_ops_helpers.h" -#define ropParith(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropParith(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } ropParith(PADDB) ropParith(PADDW) diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index 29a28e14f..6e5010446 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -13,31 +13,28 @@ #include "codegen_ops_mmx_cmp.h" #include "codegen_ops_helpers.h" -#define ropPcmp(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropPcmp(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } ropPcmp(PCMPEQB) ropPcmp(PCMPEQW) diff --git a/src/codegen_new/codegen_ops_mmx_loadstore.c b/src/codegen_new/codegen_ops_mmx_loadstore.c index ebdf81555..a20e18e68 100644 --- a/src/codegen_new/codegen_ops_mmx_loadstore.c +++ b/src/codegen_new/codegen_ops_mmx_loadstore.c @@ -13,104 +13,96 @@ #include "codegen_ops_mmx_loadstore.h" #include "codegen_ops_helpers.h" -uint32_t ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVD_r_d(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_MM(dest_reg), IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVD_d_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - if (cpu_iscyrix && in_smm) - return 0; + if (cpu_iscyrix && in_smm) + return 0; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); - uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); + uop_MOVZX(ir, IREG_temp0, IREG_MM(src_reg)); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVQ_r_q(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_MM(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOVQ_q_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 7); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_MM(src_reg)); + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_logic.c b/src/codegen_new/codegen_ops_mmx_logic.c index 24dc2b4c7..664bfd14c 100644 --- a/src/codegen_new/codegen_ops_mmx_logic.c +++ b/src/codegen_new/codegen_ops_mmx_logic.c @@ -13,99 +13,91 @@ #include "codegen_ops_mmx_logic.h" #include "codegen_ops_helpers.h" -uint32_t ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPAND(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_AND(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPANDN(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_ANDN(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_OR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } -uint32_t ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPXOR(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + int dest_reg = (fetchdat >> 3) & 7; - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); - } - else - { - x86seg *target_seg; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); + } else { + x86seg *target_seg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); - uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); + uop_XOR(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); + } - return op_pc + 1; + return op_pc + 1; } diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 87b562d17..700cb7fbf 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -13,31 +13,28 @@ #include "codegen_ops_mmx_pack.h" #include "codegen_ops_helpers.h" -#define ropPpack(func) \ -uint32_t rop ## func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int dest_reg = (fetchdat >> 3) & 7; \ - \ - uop_MMX_ENTER(ir); \ - codegen_mark_code_present(block, cs+op_pc, 1); \ - if ((fetchdat & 0xc0) == 0xc0) \ - { \ - int src_reg = fetchdat & 7; \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ - } \ - else \ - { \ - x86seg *target_seg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ - codegen_check_seg_read(block, ir, target_seg); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ - uop_ ## func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ - } \ - \ - return op_pc + 1; \ -} +#define ropPpack(func) \ + uint32_t rop##func(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int dest_reg = (fetchdat >> 3) & 7; \ + \ + uop_MMX_ENTER(ir); \ + codegen_mark_code_present(block, cs + op_pc, 1); \ + if ((fetchdat & 0xc0) == 0xc0) { \ + int src_reg = fetchdat & 7; \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_MM(src_reg)); \ + } else { \ + x86seg *target_seg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); \ + codegen_check_seg_read(block, ir, target_seg); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_Q, ireg_seg_base(target_seg), IREG_eaaddr); \ + uop_##func(ir, IREG_MM(dest_reg), IREG_MM(dest_reg), IREG_temp0_Q); \ + } \ + \ + return op_pc + 1; \ + } ropPpack(PACKSSWB) ropPpack(PACKSSDW) diff --git a/src/codegen_new/codegen_ops_mmx_shift.c b/src/codegen_new/codegen_ops_mmx_shift.c index bb5277ef3..32449d188 100644 --- a/src/codegen_new/codegen_ops_mmx_shift.c +++ b/src/codegen_new/codegen_ops_mmx_shift.c @@ -13,84 +13,81 @@ #include "codegen_ops_mmx_shift.h" #include "codegen_ops_helpers.h" -uint32_t ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPSxxW_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - switch (op) - { - case 0x10: /*PSRLW*/ - uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAW*/ - uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLW*/ - uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default: - return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLW*/ + uop_PSRLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAW*/ + uop_PSRAW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLW*/ + uop_PSLLW_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPSxxD_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - switch (op) - { - case 0x10: /*PSRLD*/ - uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAD*/ - uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLD*/ - uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default: - return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLD*/ + uop_PSRLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAD*/ + uop_PSRAD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLD*/ + uop_PSLLD_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } -uint32_t ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPSxxQ_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = fastreadb(cs + op_pc + 1); + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = fastreadb(cs + op_pc + 1); - uop_MMX_ENTER(ir); - codegen_mark_code_present(block, cs+op_pc, 1); - switch (op) - { - case 0x10: /*PSRLQ*/ - uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x20: /*PSRAQ*/ - uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - case 0x30: /*PSLLQ*/ - uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); - break; - default: - return 0; + uop_MMX_ENTER(ir); + codegen_mark_code_present(block, cs + op_pc, 1); + switch (op) { + case 0x10: /*PSRLQ*/ + uop_PSRLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x20: /*PSRAQ*/ + uop_PSRAQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + case 0x30: /*PSLLQ*/ + uop_PSLLQ_IMM(ir, IREG_MM(reg), IREG_MM(reg), shift); + break; + default: + return 0; + } - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; } diff --git a/src/codegen_new/codegen_ops_mov.c b/src/codegen_new/codegen_ops_mov.c index eb748a027..68e8fb011 100644 --- a/src/codegen_new/codegen_ops_mov.c +++ b/src/codegen_new/codegen_ops_mov.c @@ -11,763 +11,718 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_mov.h" -uint32_t ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_rb_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint8_t imm = fastreadb(cs + op_pc); + uint8_t imm = fastreadb(cs + op_pc); - uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); + uop_MOV_IMM(ir, IREG_8(opcode & 7), imm); - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; } -uint32_t ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_rw_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uint16_t imm = fastreadw(cs + op_pc); + uint16_t imm = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); + uop_MOV_IMM(ir, IREG_16(opcode & 7), imm); - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; } -uint32_t ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_rl_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); - } - else - { - fetchdat = fastreadl(cs + op_pc); - uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); - codegen_mark_code_present(block, cs+op_pc, 4); - } - return op_pc + 4; + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_32(opcode & 7), cs + op_pc); + } else { + fetchdat = fastreadl(cs + op_pc); + uop_MOV_IMM(ir, IREG_32(opcode & 7), fetchdat); + codegen_mark_code_present(block, cs + op_pc, 4); + } + return op_pc + 4; } - - -uint32_t ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_b_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int src_reg = (fetchdat >> 3) & 7; + int src_reg = (fetchdat >> 3) & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); - } - - return op_pc + 1; -} -uint32_t ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); - } - - return op_pc + 1; -} -uint32_t ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); - } - - return op_pc + 1; -} -uint32_t ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } - - return op_pc + 1; -} -uint32_t ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } - - return op_pc + 1; -} -uint32_t ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int dest_reg = (fetchdat >> 3) & 7; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); - } - - return op_pc + 1; -} - -uint32_t ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr = 0; - - if (op_32 & 0x200) - { - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); - } - else - { - addr = fastreadl(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 4); - } - } - else - { - addr = fastreadw(cs + op_pc); - codegen_mark_code_present(block, cs+op_pc, 2); - } - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_read(block, ir, op_ea_seg); - if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) - uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); - else - uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); - - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -uint32_t ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} -uint32_t ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t addr; - - if (op_32 & 0x200) - addr = fastreadl(cs + op_pc); - else - addr = fastreadw(cs + op_pc); - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - codegen_check_seg_write(block, ir, op_ea_seg); - uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); - - codegen_mark_code_present(block, cs+op_pc, (op_32 & 0x200) ? 4 : 2); - return op_pc + ((op_32 & 0x200) ? 4 : 2); -} - -uint32_t ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } else { x86seg *target_seg; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - imm = fastreadb(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_8(dest_reg), imm); - } - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadb(cs + op_pc + 1); - uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } - - codegen_mark_code_present(block, cs+op_pc+1, 1); - return op_pc + 2; -} -uint32_t ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg; - uint16_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - imm = fastreadw(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_16(dest_reg), imm); - } - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadw(cs + op_pc + 1); - uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } - - codegen_mark_code_present(block, cs+op_pc+1, 2); - return op_pc + 3; -} -uint32_t ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg; - uint32_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - imm = fastreadl(cs + op_pc + 1); - uop_MOV_IMM(ir, IREG_32(dest_reg), imm); - } - else - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - imm = fastreadl(cs + op_pc + 1); - uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); - } - - codegen_mark_code_present(block, cs+op_pc+1, 4); - return op_pc + 5; -} - -uint32_t ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg; - - codegen_mark_code_present(block, cs+op_pc, 1); - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - src_reg = IREG_ES_seg_W; - break; - case 0x08: /*CS*/ - src_reg = IREG_CS_seg_W; - break; - case 0x18: /*DS*/ - src_reg = IREG_DS_seg_W; - break; - case 0x10: /*SS*/ - src_reg = IREG_SS_seg_W; - break; - case 0x20: /*FS*/ - src_reg = IREG_FS_seg_W; - break; - case 0x28: /*GS*/ - src_reg = IREG_GS_seg_W; - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOV(ir, IREG_16(dest_reg), src_reg); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); - } - - return op_pc + 1; -} -uint32_t ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg; - - codegen_mark_code_present(block, cs+op_pc, 1); - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - src_reg = IREG_ES_seg_W; - break; - case 0x08: /*CS*/ - src_reg = IREG_CS_seg_W; - break; - case 0x18: /*DS*/ - src_reg = IREG_DS_seg_W; - break; - case 0x10: /*SS*/ - src_reg = IREG_SS_seg_W; - break; - case 0x20: /*FS*/ - src_reg = IREG_FS_seg_W; - break; - case 0x28: /*GS*/ - src_reg = IREG_GS_seg_W; - break; - default: - return 0; - } - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), src_reg); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); - } - - return op_pc + 1; -} - -uint32_t ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int src_reg; - x86seg *rseg; - - codegen_mark_code_present(block, cs+op_pc, 1); - switch (fetchdat & 0x38) - { - case 0x00: /*ES*/ - rseg = &cpu_state.seg_es; - break; - case 0x18: /*DS*/ - rseg = &cpu_state.seg_ds; - break; - case 0x20: /*FS*/ - rseg = &cpu_state.seg_fs; - break; - case 0x28: /*GS*/ - rseg = &cpu_state.seg_gs; - break; - default: - return 0; - } uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 0); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_8(src_reg)); + } - if ((fetchdat & 0xc0) == 0xc0) - { - uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); - src_reg = IREG_temp0_W; - } - else - { - x86seg *target_seg; + return op_pc + 1; +} +uint32_t +ropMOV_w_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - src_reg = IREG_temp0_W; - } + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; - uop_LOAD_SEG(ir, rseg, src_reg); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_16(src_reg)); + } - return op_pc + 1; + return op_pc + 1; +} +uint32_t +ropMOV_l_r(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 3); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_32(src_reg)); + } + + return op_pc + 1; +} +uint32_t +ropMOV_r_b(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_8(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_8(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; +} +uint32_t +ropMOV_r_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_16(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; +} +uint32_t +ropMOV_r_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOV(ir, IREG_32(dest_reg), IREG_32(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_32(dest_reg), ireg_seg_base(target_seg), IREG_eaaddr); + } + + return op_pc + 1; } -uint32_t ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_AL_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AL, ireg_seg_base(op_ea_seg), addr); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_AX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + uop_MEM_LOAD_ABS(ir, IREG_AX, ireg_seg_base(op_ea_seg), addr); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_EAX_abs(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr = 0; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + if (op_32 & 0x200) { + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + LOAD_IMMEDIATE_FROM_RAM_32(block, ir, IREG_eaaddr, cs + op_pc); + } else { + addr = fastreadl(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 4); } - else - { - x86seg *target_seg; + } else { + addr = fastreadw(cs + op_pc); + codegen_mark_code_present(block, cs + op_pc, 2); + } - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_read(block, ir, op_ea_seg); + if ((block->flags & CODEBLOCK_NO_IMMEDIATES) && (op_32 & 0x200)) + uop_MEM_LOAD_REG(ir, IREG_EAX, ireg_seg_base(op_ea_seg), IREG_eaaddr); + else + uop_MEM_LOAD_ABS(ir, IREG_EAX, ireg_seg_base(op_ea_seg), addr); - return op_pc + 1; + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_abs_AL(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AL); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_abs_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_AX); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } -uint32_t ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_abs_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int dest_reg = (fetchdat >> 3) & 7; + uint32_t addr; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int src_reg = fetchdat & 7; - uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); - } - else - { - x86seg *target_seg; + if (op_32 & 0x200) + addr = fastreadl(cs + op_pc); + else + addr = fastreadw(cs + op_pc); - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_read(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); - } + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + codegen_check_seg_write(block, ir, op_ea_seg); + uop_MEM_STORE_ABS(ir, ireg_seg_base(op_ea_seg), addr, IREG_EAX); - return op_pc + 1; + codegen_mark_code_present(block, cs + op_pc, (op_32 & 0x200) ? 4 : 2); + return op_pc + ((op_32 & 0x200) ? 4 : 2); } - -uint32_t ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropMOV_b_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int reg2 = IREG_16(opcode & 7); + x86seg *target_seg; + uint8_t imm; - uop_MOV(ir, IREG_temp0_W, IREG_AX); - uop_MOV(ir, IREG_AX, reg2); + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + imm = fastreadb(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_8(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadb(cs + op_pc + 1); + uop_MEM_STORE_IMM_8(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + codegen_mark_code_present(block, cs + op_pc + 1, 1); + return op_pc + 2; +} +uint32_t +ropMOV_w_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint16_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + imm = fastreadw(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_16(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadw(cs + op_pc + 1); + uop_MEM_STORE_IMM_16(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + codegen_mark_code_present(block, cs + op_pc + 1, 2); + return op_pc + 3; +} +uint32_t +ropMOV_l_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg; + uint32_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + imm = fastreadl(cs + op_pc + 1); + uop_MOV_IMM(ir, IREG_32(dest_reg), imm); + } else { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + imm = fastreadl(cs + op_pc + 1); + uop_MEM_STORE_IMM_32(ir, ireg_seg_base(target_seg), IREG_eaaddr, imm); + } + + codegen_mark_code_present(block, cs + op_pc + 1, 4); + return op_pc + 5; +} + +uint32_t +ropMOV_w_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOV(ir, IREG_16(dest_reg), src_reg); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + CHECK_SEG_LIMITS(block, ir, target_seg, IREG_eaaddr, 1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } + + return op_pc + 1; +} +uint32_t +ropMOV_l_seg(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + src_reg = IREG_ES_seg_W; + break; + case 0x08: /*CS*/ + src_reg = IREG_CS_seg_W; + break; + case 0x18: /*DS*/ + src_reg = IREG_DS_seg_W; + break; + case 0x10: /*SS*/ + src_reg = IREG_SS_seg_W; + break; + case 0x20: /*FS*/ + src_reg = IREG_FS_seg_W; + break; + case 0x28: /*GS*/ + src_reg = IREG_GS_seg_W; + break; + default: + return 0; + } + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), src_reg); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, src_reg); + } + + return op_pc + 1; +} + +uint32_t +ropMOV_seg_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int src_reg; + x86seg *rseg; + + codegen_mark_code_present(block, cs + op_pc, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ES*/ + rseg = &cpu_state.seg_es; + break; + case 0x18: /*DS*/ + rseg = &cpu_state.seg_ds; + break; + case 0x20: /*FS*/ + rseg = &cpu_state.seg_fs; + break; + case 0x28: /*GS*/ + rseg = &cpu_state.seg_gs; + break; + default: + return 0; + } + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if ((fetchdat & 0xc0) == 0xc0) { + uop_MOV(ir, IREG_temp0_W, IREG_16(fetchdat & 7)); + src_reg = IREG_temp0_W; + } else { + x86seg *target_seg; + + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + src_reg = IREG_temp0_W; + } + + uop_LOAD_SEG(ir, rseg, src_reg); + + return op_pc + 1; +} + +uint32_t +ropMOVSX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_16(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVSX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVSX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVSX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVSX(ir, IREG_32(dest_reg), IREG_temp0_W); + } + + return op_pc + 1; +} + +uint32_t +ropMOVZX_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_16(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_16(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVZX_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_8(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropMOVZX_32_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int dest_reg = (fetchdat >> 3) & 7; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int src_reg = fetchdat & 7; + uop_MOVZX(ir, IREG_32(dest_reg), IREG_16(src_reg)); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_read(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MOVZX(ir, IREG_32(dest_reg), IREG_temp0_W); + } + + return op_pc + 1; +} + +uint32_t +ropXCHG_AX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg2 = IREG_16(opcode & 7); + + uop_MOV(ir, IREG_temp0_W, IREG_AX); + uop_MOV(ir, IREG_AX, reg2); + uop_MOV(ir, reg2, IREG_temp0_W); + + return op_pc; +} +uint32_t +ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg2 = IREG_32(opcode & 7); + + uop_MOV(ir, IREG_temp0, IREG_EAX); + uop_MOV(ir, IREG_EAX, reg2); + uop_MOV(ir, reg2, IREG_temp0); + + return op_pc; +} + +uint32_t +ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_8((fetchdat >> 3) & 7); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_8(fetchdat & 7); + + uop_MOV(ir, IREG_temp0_B, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0_B); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_B); + } + + return op_pc + 1; +} +uint32_t +ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_16((fetchdat >> 3) & 7); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_16(fetchdat & 7); + + uop_MOV(ir, IREG_temp0_W, reg1); + uop_MOV(ir, reg1, reg2); uop_MOV(ir, reg2, IREG_temp0_W); + } else { + x86seg *target_seg; - return op_pc; -} -uint32_t ropXCHG_EAX(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg2 = IREG_32(opcode & 7); - - uop_MOV(ir, IREG_temp0, IREG_EAX); - uop_MOV(ir, IREG_EAX, reg2); - uop_MOV(ir, reg2, IREG_temp0); - - return op_pc; -} - -uint32_t ropXCHG_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg1 = IREG_8((fetchdat >> 3) & 7); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int reg2 = IREG_8(fetchdat & 7); - - uop_MOV(ir, IREG_temp0_B, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0_B); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0_B); - } - - return op_pc + 1; -} -uint32_t ropXCHG_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg1 = IREG_16((fetchdat >> 3) & 7); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int reg2 = IREG_16(fetchdat & 7); - - uop_MOV(ir, IREG_temp0_W, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0_W); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0_W); - } - - return op_pc + 1; -} -uint32_t ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - int reg1 = IREG_32((fetchdat >> 3) & 7); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int reg2 = IREG_32(fetchdat & 7); - - uop_MOV(ir, IREG_temp0, reg1); - uop_MOV(ir, reg1, reg2); - uop_MOV(ir, reg2, IREG_temp0); - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); - uop_MOV(ir, reg1, IREG_temp0); - } - - return op_pc + 1; -} - -uint32_t ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); - uop_MOVZX(ir, IREG_eaaddr, IREG_AL); - uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); - if (!(op_32 & 0x200)) - uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0_W); + } - uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); - - return op_pc; + return op_pc + 1; +} +uint32_t +ropXCHG_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + int reg1 = IREG_32((fetchdat >> 3) & 7); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int reg2 = IREG_32(fetchdat & 7); + + uop_MOV(ir, IREG_temp0, reg1); + uop_MOV(ir, reg1, reg2); + uop_MOV(ir, reg2, IREG_temp0); + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, reg1); + uop_MOV(ir, reg1, IREG_temp0); + } + + return op_pc + 1; +} + +uint32_t +ropXLAT(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + uop_MOVZX(ir, IREG_eaaddr, IREG_AL); + uop_ADD(ir, IREG_eaaddr, IREG_eaaddr, IREG_EBX); + if (!(op_32 & 0x200)) + uop_AND_IMM(ir, IREG_eaaddr, IREG_eaaddr, 0xffff); + + uop_MEM_LOAD_REG(ir, IREG_AL, ireg_seg_base(op_ea_seg), IREG_eaaddr); + + return op_pc; } diff --git a/src/codegen_new/codegen_ops_shift.c b/src/codegen_new/codegen_ops_shift.c index 370585bf2..8ccf7d9e7 100644 --- a/src/codegen_new/codegen_ops_shift.c +++ b/src/codegen_new/codegen_ops_shift.c @@ -13,1126 +13,1097 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_shift.h" -static uint32_t shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) +static uint32_t +shift_common_8(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR_IMM(ir, IREG_8(dest_reg), IREG_8(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -static uint32_t shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} -static uint32_t shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x28: /*SHR*/ - uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x38: /*SAR*/ - uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, count); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -static uint32_t shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count_reg) -{ - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - default: - return 0; - } - } - else - { - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, count_reg); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - uint8_t imm; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + default: return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - if (imm) - return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; - return op_pc+1; -} -uint32_t ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - uint8_t imm; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_B, IREG_temp0_B, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + default: return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); + } - if (imm) - return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; - return op_pc+1; -} -uint32_t ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - } - if (block->flags & CODEBLOCK_NO_IMMEDIATES) - { - uint32_t new_pc; - int jump_uop; - - LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); - uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); - jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); - - new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; - uop_NOP_BARRIER(ir); - uop_set_jump_dest(ir, jump_uop); - return new_pc; - } - else - { - uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (imm) - return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; - } - return op_pc+1; + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static uint32_t +shift_common_16(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - } - - return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); -} -uint32_t ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - } - - return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); -} -uint32_t ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - } - - return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); -} - -uint32_t ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - if (!(CL & 0x1f) || !block->ins) - return 0; - - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); - uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - if (!(CL & 0x1f) || !block->ins) - return 0; - - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); - uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); - uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} -uint32_t ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ - return 0; - - if (!(CL & 0x1f) || !block->ins) - return 0; - - uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); - uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x28: /*SHR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - case 0x38: /*SAR*/ - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - break; - - default: - return 0; - } - } - else - { - x86seg *target_seg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); - - switch (fetchdat & 0x38) - { - case 0x00: /*ROL*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x08: /*ROR*/ - uop_CALL_FUNC(ir, flags_rebuild); - uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - break; - - case 0x20: case 0x30: /*SHL*/ - uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x28: /*SHR*/ - uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - case 0x38: /*SAR*/ - uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); - uop_MOV(ir, IREG_flags_op1, IREG_temp0); - uop_MOV(ir, IREG_flags_op2, IREG_temp2); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); - uop_MOV(ir, IREG_flags_res, IREG_temp1); - break; - - default: - return 0; - } - } - - codegen_flags_changed = 1; - return op_pc + 1; -} - -uint32_t ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); - uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SHL_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); - - uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); - uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - - uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); - uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); - } - - return op_pc+2; -} -uint32_t ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; - - uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); - uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); - - uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); - uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - - uop_MOV(ir, IREG_flags_op1, IREG_temp2); - uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); - } - - return op_pc+2; -} -uint32_t ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); - - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + break; + case 0x28: /*SHR*/ uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); - uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); - uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SHR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + break; - uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); - uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); - uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR_IMM(ir, IREG_16(dest_reg), IREG_16(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); - - uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); - } + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; - return op_pc+2; + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1_W, IREG_temp0_W, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; } -uint32_t ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +static uint32_t +shift_common_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count) { - x86seg *target_seg = NULL; - int src_reg = (fetchdat >> 3) & 7; - uint8_t imm; + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) != 0xc0) - { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); - } - imm = fastreadb(cs + op_pc + 1) & 0x1f; - codegen_mark_code_present(block, cs+op_pc+1, 1); + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; - if (!imm) - return op_pc+2; - - if ((fetchdat & 0xc0) == 0xc0) - { - int dest_reg = fetchdat & 7; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + case 0x20: + case 0x30: /*SHL*/ uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); - uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); - uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); - uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_SHL_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); - } - else - { - codegen_check_seg_write(block, ir, target_seg); - uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + break; - uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); - uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); - uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR_IMM(ir, IREG_32(dest_reg), IREG_32(dest_reg), count); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL_IMM(ir, IREG_temp0, IREG_temp0, count); uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - - uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); uop_MOV(ir, IREG_flags_res, IREG_temp0); - uop_MOV_IMM(ir, IREG_flags_op2, imm); - uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); - } + break; - return op_pc+2; + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR_IMM(ir, IREG_temp0, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR_IMM(ir, IREG_temp1, IREG_temp0, count); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, count); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +static uint32_t +shift_common_variable_32(ir_data_t *ir, uint32_t fetchdat, uint32_t op_pc, x86seg *target_seg, int count_reg) +{ + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), count_reg); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } else { + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, count_reg); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, count_reg); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropC0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (imm) + return shift_common_8(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc + 1; +} +uint32_t +ropC1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + uint8_t imm; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (imm) + return shift_common_16(ir, fetchdat, op_pc, target_seg, imm) + 1; + return op_pc + 1; +} +uint32_t +ropC1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + if (block->flags & CODEBLOCK_NO_IMMEDIATES) { + uint32_t new_pc; + int jump_uop; + + LOAD_IMMEDIATE_FROM_RAM_8(block, ir, IREG_temp2, cs + op_pc + 1); + uop_AND_IMM(ir, IREG_temp2, IREG_temp2, 0x1f); + jump_uop = uop_CMP_IMM_JZ_DEST(ir, IREG_temp2, 0); + + new_pc = shift_common_variable_32(ir, fetchdat, op_pc, target_seg, IREG_temp2) + 1; + uop_NOP_BARRIER(ir); + uop_set_jump_dest(ir, jump_uop); + return new_pc; + } else { + uint8_t imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (imm) + return shift_common_32(ir, fetchdat, op_pc, target_seg, imm) + 1; + } + return op_pc + 1; +} + +uint32_t +ropD0(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_8(ir, fetchdat, op_pc, target_seg, 1); +} +uint32_t +ropD1_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_16(ir, fetchdat, op_pc, target_seg, 1); +} +uint32_t +ropD1_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + } + + return shift_common_32(ir, fetchdat, op_pc, target_seg, 1); +} + +uint32_t +ropD2(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHL(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SHR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_8(dest_reg)); + uop_SAR(ir, IREG_8(dest_reg), IREG_8(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_8(dest_reg)); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_B, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_B); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_B); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_B, IREG_temp0_B, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_B); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_B); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR8); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_B); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropD3_w(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SAR(ir, IREG_16(dest_reg), IREG_16(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1_W, IREG_temp0_W, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1_W); + uop_MOVZX(ir, IREG_flags_op1, IREG_temp0_W); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR16); + uop_MOVZX(ir, IREG_flags_res, IREG_temp1_W); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} +uint32_t +ropD3_l(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + if ((fetchdat & 0x30) == 0x10) /*RCL/RCR*/ + return 0; + + if (!(CL & 0x1f) || !block->ins) + return 0; + + uop_AND_IMM(ir, IREG_temp2, REG_ECX, 0x1f); + uop_CMP_IMM_JZ(ir, IREG_temp2, 0, codegen_exit_rout); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x28: /*SHR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + case 0x38: /*SAR*/ + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SAR(ir, IREG_32(dest_reg), IREG_32(dest_reg), IREG_temp2); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + break; + + default: + return 0; + } + } else { + x86seg *target_seg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp0, ireg_seg_base(target_seg), IREG_eaaddr); + + switch (fetchdat & 0x38) { + case 0x00: /*ROL*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROL(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROL32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x08: /*ROR*/ + uop_CALL_FUNC(ir, flags_rebuild); + uop_ROR(ir, IREG_temp0, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_ROR32); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + break; + + case 0x20: + case 0x30: /*SHL*/ + uop_SHL(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x28: /*SHR*/ + uop_SHR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + case 0x38: /*SAR*/ + uop_SAR(ir, IREG_temp1, IREG_temp0, IREG_temp2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp1); + uop_MOV(ir, IREG_flags_op1, IREG_temp0); + uop_MOV(ir, IREG_flags_op2, IREG_temp2); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SAR32); + uop_MOV(ir, IREG_flags_res, IREG_temp1); + break; + + default: + return 0; + } + } + + codegen_flags_changed = 1; + return op_pc + 1; +} + +uint32_t +ropSHLD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHL_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL16); + } + + return op_pc + 2; +} +uint32_t +ropSHLD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHL_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHL_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHR_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHL32); + } + + return op_pc + 2; +} +uint32_t +ropSHRD_16_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOVZX(ir, IREG_flags_op1, IREG_16(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0_W, IREG_16(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_16(dest_reg), IREG_temp0_W, IREG_temp1_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + uop_MOVZX(ir, IREG_flags_res, IREG_16(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2_W, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHR_IMM(ir, IREG_temp0_W, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1_W, IREG_16(src_reg), 16 - imm); + uop_OR(ir, IREG_temp0_W, IREG_temp0_W, IREG_temp1_W); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + + uop_MOVZX(ir, IREG_flags_op1, IREG_temp2_W); + uop_MOVZX(ir, IREG_flags_res, IREG_temp0_W); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR16); + } + + return op_pc + 2; +} +uint32_t +ropSHRD_32_imm(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + x86seg *target_seg = NULL; + int src_reg = (fetchdat >> 3) & 7; + uint8_t imm; + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) != 0xc0) { + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 0); + } + imm = fastreadb(cs + op_pc + 1) & 0x1f; + codegen_mark_code_present(block, cs + op_pc + 1, 1); + + if (!imm) + return op_pc + 2; + + if ((fetchdat & 0xc0) == 0xc0) { + int dest_reg = fetchdat & 7; + + uop_MOV(ir, IREG_flags_op1, IREG_32(dest_reg)); + uop_SHR_IMM(ir, IREG_temp0, IREG_32(dest_reg), imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_32(dest_reg), IREG_temp0, IREG_temp1); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + uop_MOV(ir, IREG_flags_res, IREG_32(dest_reg)); + } else { + codegen_check_seg_write(block, ir, target_seg); + uop_MEM_LOAD_REG(ir, IREG_temp2, ireg_seg_base(target_seg), IREG_eaaddr); + + uop_SHR_IMM(ir, IREG_temp0, IREG_temp2, imm); + uop_SHL_IMM(ir, IREG_temp1, IREG_32(src_reg), 32 - imm); + uop_OR(ir, IREG_temp0, IREG_temp0, IREG_temp1); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + + uop_MOV(ir, IREG_flags_op1, IREG_temp2); + uop_MOV(ir, IREG_flags_res, IREG_temp0); + uop_MOV_IMM(ir, IREG_flags_op2, imm); + uop_MOV_IMM(ir, IREG_flags_op, FLAGS_SHR32); + } + + return op_pc + 2; } diff --git a/src/codegen_new/codegen_ops_stack.c b/src/codegen_new/codegen_ops_stack.c index ff421488e..b7afdce25 100644 --- a/src/codegen_new/codegen_ops_stack.c +++ b/src/codegen_new/codegen_ops_stack.c @@ -12,248 +12,243 @@ #include "codegen_ops_helpers.h" #include "codegen_ops_misc.h" -uint32_t ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSH_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_16(opcode & 7)); + SUB_SP(ir, 2); - return op_pc; + return op_pc; } -uint32_t ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSH_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); - SUB_SP(ir, 4); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_32(opcode & 7)); + SUB_SP(ir, 4); - return op_pc; + return op_pc; } -uint32_t ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOP_r16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_SP) + ADD_SP(ir, 2); + + return op_pc; +} +uint32_t +ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); + } + if ((opcode & 7) != REG_ESP) + ADD_SP(ir, 4); + + return op_pc; +} + +uint32_t +ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = fastreadw(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); + + codegen_mark_code_present(block, cs + op_pc, 2); + return op_pc + 2; +} +uint32_t +ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t imm = fastreadl(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); + + codegen_mark_code_present(block, cs + op_pc, 4); + return op_pc + 4; +} + +uint32_t +ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint16_t imm = (int16_t) (int8_t) fastreadb(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 2); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} +uint32_t +ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uint32_t imm = (int32_t) (int8_t) fastreadb(cs + op_pc); + int sp_reg; + + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); + SUB_SP(ir, 4); + + codegen_mark_code_present(block, cs + op_pc, 1); + return op_pc + 1; +} + +uint32_t +ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +{ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } else { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); + codegen_check_seg_write(block, ir, target_seg); if (stack32) - uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_16(opcode & 7), IREG_SS_base, IREG_eaaddr); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); } - if ((opcode & 7) != REG_SP) - ADD_SP(ir, 2); - return op_pc; + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + } + + if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) + ADD_SP(ir, 2); + + return op_pc + 1; } -uint32_t ropPOP_r32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + + codegen_mark_code_present(block, cs + op_pc, 1); + if ((fetchdat & 0xc0) == 0xc0) { + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); + } + } else { + x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); + codegen_check_seg_write(block, ir, target_seg); if (stack32) - uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_32(opcode & 7), IREG_SS_base, IREG_eaaddr); - } - if ((opcode & 7) != REG_ESP) - ADD_SP(ir, 4); - - return op_pc; -} - -uint32_t ropPUSH_imm_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm = fastreadw(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 2); - - codegen_mark_code_present(block, cs+op_pc, 2); - return op_pc + 2; -} -uint32_t ropPUSH_imm_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t imm = fastreadl(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 4); - - codegen_mark_code_present(block, cs+op_pc, 4); - return op_pc + 4; -} - -uint32_t ropPUSH_imm_16_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint16_t imm = (int16_t)(int8_t)fastreadb(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_IMM_16(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 2); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} -uint32_t ropPUSH_imm_32_8(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uint32_t imm = (int32_t)(int8_t)fastreadb(cs + op_pc); - int sp_reg; - - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_IMM_32(ir, IREG_SS_base, sp_reg, imm); - SUB_SP(ir, 4); - - codegen_mark_code_present(block, cs+op_pc, 1); - return op_pc + 1; -} - -uint32_t ropPOP_W(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_16(fetchdat & 7), IREG_SS_base, IREG_eaaddr); - } - } - else - { - x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 2); - codegen_check_seg_write(block, ir, target_seg); - - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_temp0, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_temp0); - } - - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0_W); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); + else { + uop_MOVZX(ir, IREG_temp0, IREG_SP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); } - if ((fetchdat & 0xc7) != (0xc0 | REG_SP)) - ADD_SP(ir, 2); + uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); + } - return op_pc + 1; -} -uint32_t ropPOP_L(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) -{ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) + ADD_SP(ir, 4); - codegen_mark_code_present(block, cs+op_pc, 1); - if ((fetchdat & 0xc0) == 0xc0) - { - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_32(fetchdat & 7), IREG_SS_base, IREG_eaaddr); - } - } - else - { - x86seg *target_seg = codegen_generate_ea(ir, op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32, 4); - codegen_check_seg_write(block, ir, target_seg); - - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_ESP); - else - { - uop_MOVZX(ir, IREG_temp0, IREG_SP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_temp0); - } - - uop_MEM_STORE_REG(ir, ireg_seg_base(target_seg), IREG_eaaddr, IREG_temp0); - } - - if ((fetchdat & 0xc7) != (0xc0 | REG_ESP)) - ADD_SP(ir, 4); - - return op_pc + 1; + return op_pc + 1; } -#define ROP_PUSH_SEG(seg) \ -uint32_t ropPUSH_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_ ## seg ## _seg_W); \ - SUB_SP(ir, 2); \ - \ - return op_pc; \ -} \ -uint32_t ropPUSH_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - int sp_reg; \ - \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ - uop_MOVZX(ir, IREG_temp0, IREG_ ## seg ## _seg_W); \ - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ - SUB_SP(ir, 4); \ - \ - return op_pc; \ -} - -#define ROP_POP_SEG(seg, rseg) \ -uint32_t ropPOP_ ## seg ## _16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else \ - { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 2); \ - \ - return op_pc; \ -} \ -uint32_t ropPOP_ ## seg ## _32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ -{ \ - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ - \ - if (stack32) \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ - else \ - { \ - uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ - } \ - uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ - ADD_SP(ir, 4); \ - \ - return op_pc; \ -} +#define ROP_PUSH_SEG(seg) \ + uint32_t ropPUSH_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_##seg##_seg_W); \ + SUB_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPUSH_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + int sp_reg; \ + \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); \ + uop_MOVZX(ir, IREG_temp0, IREG_##seg##_seg_W); \ + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_temp0); \ + SUB_SP(ir, 4); \ + \ + return op_pc; \ + } +#define ROP_POP_SEG(seg, rseg) \ + uint32_t ropPOP_##seg##_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 2); \ + \ + return op_pc; \ + } \ + uint32_t ropPOP_##seg##_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) \ + { \ + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); \ + \ + if (stack32) \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_ESP); \ + else { \ + uop_MOVZX(ir, IREG_eaaddr, IREG_SP); \ + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); \ + } \ + uop_LOAD_SEG(ir, &rseg, IREG_temp0_W); \ + ADD_SP(ir, 4); \ + \ + return op_pc; \ + } ROP_PUSH_SEG(CS) ROP_PUSH_SEG(DS) @@ -266,147 +261,152 @@ ROP_POP_SEG(ES, cpu_state.seg_es) ROP_POP_SEG(FS, cpu_state.seg_fs) ROP_POP_SEG(GS, cpu_state.seg_gs) -uint32_t ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEAVE_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_BP); - uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); - } - uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); - uop_MOV(ir, IREG_BP, IREG_temp0_W); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_EBP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0_W, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_SP, IREG_BP, 2); + uop_MOV(ir, IREG_BP, IREG_temp0_W); - return op_pc; + return op_pc; } -uint32_t ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropLEAVE_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - if (stack32) - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); - else - { - uop_MOVZX(ir, IREG_eaaddr, IREG_BP); - uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); - } - uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); - uop_MOV(ir, IREG_EBP, IREG_temp0); + if (stack32) + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_EBP); + else { + uop_MOVZX(ir, IREG_eaaddr, IREG_BP); + uop_MEM_LOAD_REG(ir, IREG_temp0, IREG_SS_base, IREG_eaaddr); + } + uop_ADD_IMM(ir, IREG_ESP, IREG_EBP, 4); + uop_MOV(ir, IREG_EBP, IREG_temp0); - return op_pc; + return op_pc; } - -uint32_t ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); - SUB_SP(ir, 16); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -16); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 14, IREG_AX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_CX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 10, IREG_DX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_BX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 6, IREG_SP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_BP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_SI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_DI); + SUB_SP(ir, 16); - return op_pc; + return op_pc; } -uint32_t ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); - SUB_SP(ir, 32); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -32); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 28, IREG_EAX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 24, IREG_ECX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 20, IREG_EDX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 16, IREG_EBX); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 12, IREG_ESP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 8, IREG_EBP); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 4, IREG_ESI); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_EDI); + SUB_SP(ir, 32); - return op_pc; + return op_pc; } -uint32_t ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOPA_16(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP(ir); - uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); - ADD_SP(ir, 16); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_DI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_SI, IREG_SS_base, sp_reg, 2); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BP, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_BX, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_DX, IREG_SS_base, sp_reg, 10); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_CX, IREG_SS_base, sp_reg, 12); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_AX, IREG_SS_base, sp_reg, 14); + ADD_SP(ir, 16); - return op_pc; + return op_pc; } -uint32_t ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPOPA_32(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - sp_reg = LOAD_SP(ir); - uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); - uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); - ADD_SP(ir, 32); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + sp_reg = LOAD_SP(ir); + uop_MEM_LOAD_REG(ir, IREG_EDI, IREG_SS_base, sp_reg); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ESI, IREG_SS_base, sp_reg, 4); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBP, IREG_SS_base, sp_reg, 8); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EBX, IREG_SS_base, sp_reg, 16); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EDX, IREG_SS_base, sp_reg, 20); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_ECX, IREG_SS_base, sp_reg, 24); + uop_MEM_LOAD_REG_OFFSET(ir, IREG_EAX, IREG_SS_base, sp_reg, 28); + ADD_SP(ir, 32); - return op_pc; + return op_pc; } -uint32_t ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHF(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - return 0; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_CALL_FUNC(ir, flags_rebuild); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); - SUB_SP(ir, 2); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -2); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + SUB_SP(ir, 2); - return op_pc; + return op_pc; } -uint32_t ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) +uint32_t +ropPUSHFD(codeblock_t *block, ir_data_t *ir, uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc) { - int sp_reg; + int sp_reg; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - return 0; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) + return 0; - uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); - uop_CALL_FUNC(ir, flags_rebuild); + uop_MOV_IMM(ir, IREG_oldpc, cpu_state.oldpc); + uop_CALL_FUNC(ir, flags_rebuild); - if (cpu_CR4_mask & CR4_VME) - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); - else if (CPUID) - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); - else - uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); - sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); - uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); - uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); - SUB_SP(ir, 4); + if (cpu_CR4_mask & CR4_VME) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x3c); + else if (CPUID) + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 0x24); + else + uop_AND_IMM(ir, IREG_temp0_W, IREG_eflags, 4); + sp_reg = LOAD_SP_WITH_OFFSET(ir, -4); + uop_MEM_STORE_REG(ir, IREG_SS_base, sp_reg, IREG_flags); + uop_MEM_STORE_REG_OFFSET(ir, IREG_SS_base, sp_reg, 2, IREG_temp0_W); + SUB_SP(ir, 4); - return op_pc; + return op_pc; } diff --git a/src/codegen_new/codegen_reg.c b/src/codegen_new/codegen_reg.c index a62121af7..7cd7b418a 100644 --- a/src/codegen_new/codegen_reg.c +++ b/src/codegen_new/codegen_reg.c @@ -8,916 +8,879 @@ #include "codegen_ir_defs.h" #include "codegen_reg.h" -int max_version_refcount; +int max_version_refcount; uint16_t reg_dead_list = 0; -uint8_t reg_last_version[IREG_COUNT]; +uint8_t reg_last_version[IREG_COUNT]; reg_version_t reg_version[IREG_COUNT][256]; -ir_reg_t invalid_ir_reg = {IREG_INVALID}; +ir_reg_t invalid_ir_reg = { IREG_INVALID }; -ir_reg_t _host_regs[CODEGEN_HOST_REGS]; +ir_reg_t _host_regs[CODEGEN_HOST_REGS]; static uint8_t _host_reg_dirty[CODEGEN_HOST_REGS]; -ir_reg_t host_fp_regs[CODEGEN_HOST_FP_REGS]; +ir_reg_t host_fp_regs[CODEGEN_HOST_FP_REGS]; static uint8_t host_fp_reg_dirty[CODEGEN_HOST_FP_REGS]; -typedef struct host_reg_set_t -{ - ir_reg_t *regs; - uint8_t *dirty; - host_reg_def_t *reg_list; - uint16_t locked; - int nr_regs; +typedef struct host_reg_set_t { + ir_reg_t *regs; + uint8_t *dirty; + host_reg_def_t *reg_list; + uint16_t locked; + int nr_regs; } host_reg_set_t; static host_reg_set_t host_reg_set, host_fp_reg_set; -enum -{ - REG_BYTE, - REG_WORD, - REG_DWORD, - REG_QWORD, - REG_POINTER, - REG_DOUBLE, - REG_FPU_ST_BYTE, - REG_FPU_ST_DOUBLE, - REG_FPU_ST_QWORD +enum { + REG_BYTE, + REG_WORD, + REG_DWORD, + REG_QWORD, + REG_POINTER, + REG_DOUBLE, + REG_FPU_ST_BYTE, + REG_FPU_ST_DOUBLE, + REG_FPU_ST_QWORD }; -enum -{ - REG_INTEGER, - REG_FP +enum { + REG_INTEGER, + REG_FP }; -enum -{ - /*Register may be accessed outside of code block, and must be written - back before any control transfers*/ - REG_PERMANENT = 0, - /*Register will not be accessed outside of code block, and does not need - to be written back if there are no readers remaining*/ - REG_VOLATILE = 1 +enum { + /*Register may be accessed outside of code block, and must be written + back before any control transfers*/ + REG_PERMANENT = 0, + /*Register will not be accessed outside of code block, and does not need + to be written back if there are no readers remaining*/ + REG_VOLATILE = 1 }; struct { - int native_size; - void *p; - int type; - int is_volatile; -} ireg_data[IREG_COUNT] = -{ - [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, - [IREG_ECX] = {REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, - [IREG_EDX] = {REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, - [IREG_EBX] = {REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, - [IREG_ESP] = {REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, - [IREG_EBP] = {REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, - [IREG_ESI] = {REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, - [IREG_EDI] = {REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, + int native_size; + void *p; + int type; + int is_volatile; +} ireg_data[IREG_COUNT] = { + [IREG_EAX] = {REG_DWORD, &EAX, REG_INTEGER, REG_PERMANENT}, + [IREG_ECX] = { REG_DWORD, &ECX, REG_INTEGER, REG_PERMANENT}, + [IREG_EDX] = { REG_DWORD, &EDX, REG_INTEGER, REG_PERMANENT}, + [IREG_EBX] = { REG_DWORD, &EBX, REG_INTEGER, REG_PERMANENT}, + [IREG_ESP] = { REG_DWORD, &ESP, REG_INTEGER, REG_PERMANENT}, + [IREG_EBP] = { REG_DWORD, &EBP, REG_INTEGER, REG_PERMANENT}, + [IREG_ESI] = { REG_DWORD, &ESI, REG_INTEGER, REG_PERMANENT}, + [IREG_EDI] = { REG_DWORD, &EDI, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op] = {REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_res] = {REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op1] = {REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, - [IREG_flags_op2] = {REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op] = { REG_DWORD, &cpu_state.flags_op, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_res] = { REG_DWORD, &cpu_state.flags_res, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op1] = { REG_DWORD, &cpu_state.flags_op1, REG_INTEGER, REG_PERMANENT}, + [IREG_flags_op2] = { REG_DWORD, &cpu_state.flags_op2, REG_INTEGER, REG_PERMANENT}, - [IREG_pc] = {REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, - [IREG_oldpc] = {REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, + [IREG_pc] = { REG_DWORD, &cpu_state.pc, REG_INTEGER, REG_PERMANENT}, + [IREG_oldpc] = { REG_DWORD, &cpu_state.oldpc, REG_INTEGER, REG_PERMANENT}, - [IREG_eaaddr] = {REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, - [IREG_ea_seg] = {REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, + [IREG_eaaddr] = { REG_DWORD, &cpu_state.eaaddr, REG_INTEGER, REG_PERMANENT}, + [IREG_ea_seg] = { REG_POINTER, &cpu_state.ea_seg, REG_INTEGER, REG_PERMANENT}, - [IREG_op32] = {REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, - [IREG_ssegsx] = {REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, + [IREG_op32] = { REG_DWORD, &cpu_state.op32, REG_INTEGER, REG_PERMANENT}, + [IREG_ssegsx] = { REG_BYTE, &cpu_state.ssegs, REG_INTEGER, REG_PERMANENT}, - [IREG_rm_mod_reg] = {REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, + [IREG_rm_mod_reg] = { REG_DWORD, &cpu_state.rm_data.rm_mod_reg_data, REG_INTEGER, REG_PERMANENT}, #ifdef USE_ACYCS - [IREG_acycs] = {REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT}, + [IREG_acycs] = { REG_DWORD, &acycs, REG_INTEGER, REG_PERMANENT}, #endif - [IREG_cycles] = {REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, + [IREG_cycles] = { REG_DWORD, &cpu_state._cycles, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_base] = {REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_base] = {REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_base] = {REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_base] = {REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_base] = {REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_base] = {REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_base] = { REG_DWORD, &cpu_state.seg_cs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_base] = { REG_DWORD, &cpu_state.seg_ds.base, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_base] = { REG_DWORD, &cpu_state.seg_es.base, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_base] = { REG_DWORD, &cpu_state.seg_fs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_base] = { REG_DWORD, &cpu_state.seg_gs.base, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_base] = { REG_DWORD, &cpu_state.seg_ss.base, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_seg] = {REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_seg] = {REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_seg] = {REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_seg] = {REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_seg] = {REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_seg] = {REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_seg] = { REG_WORD, &cpu_state.seg_cs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_seg] = { REG_WORD, &cpu_state.seg_ds.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_seg] = { REG_WORD, &cpu_state.seg_es.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_seg] = { REG_WORD, &cpu_state.seg_fs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_seg] = { REG_WORD, &cpu_state.seg_gs.seg, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_seg] = { REG_WORD, &cpu_state.seg_ss.seg, REG_INTEGER, REG_PERMANENT}, - [IREG_FPU_TOP] = {REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, + [IREG_FPU_TOP] = { REG_DWORD, &cpu_state.TOP, REG_INTEGER, REG_PERMANENT}, - [IREG_ST0] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST1] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST2] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST3] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST4] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST5] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST6] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_ST7] = {REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST0] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST1] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST2] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST3] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST4] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST5] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST6] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, + [IREG_ST7] = { REG_FPU_ST_DOUBLE, &cpu_state.ST[0], REG_FP, REG_PERMANENT}, - [IREG_tag0] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag1] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag2] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag3] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag4] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag5] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag6] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_tag7] = {REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag0] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag1] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag2] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag3] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag4] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag5] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag6] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, + [IREG_tag7] = { REG_FPU_ST_BYTE, &cpu_state.tag[0], REG_INTEGER, REG_PERMANENT}, - [IREG_ST0_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST1_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST2_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST3_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST4_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST5_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST6_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_ST7_i64] = {REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST0_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST1_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST2_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST3_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST4_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST5_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST6_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_ST7_i64] = { REG_FPU_ST_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM0x] = {REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, - [IREG_MM1x] = {REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, - [IREG_MM2x] = {REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, - [IREG_MM3x] = {REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, - [IREG_MM4x] = {REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, - [IREG_MM5x] = {REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, - [IREG_MM6x] = {REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, - [IREG_MM7x] = {REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, + [IREG_MM0x] = { REG_QWORD, &cpu_state.MM[0], REG_FP, REG_PERMANENT}, + [IREG_MM1x] = { REG_QWORD, &cpu_state.MM[1], REG_FP, REG_PERMANENT}, + [IREG_MM2x] = { REG_QWORD, &cpu_state.MM[2], REG_FP, REG_PERMANENT}, + [IREG_MM3x] = { REG_QWORD, &cpu_state.MM[3], REG_FP, REG_PERMANENT}, + [IREG_MM4x] = { REG_QWORD, &cpu_state.MM[4], REG_FP, REG_PERMANENT}, + [IREG_MM5x] = { REG_QWORD, &cpu_state.MM[5], REG_FP, REG_PERMANENT}, + [IREG_MM6x] = { REG_QWORD, &cpu_state.MM[6], REG_FP, REG_PERMANENT}, + [IREG_MM7x] = { REG_QWORD, &cpu_state.MM[7], REG_FP, REG_PERMANENT}, - [IREG_NPXCx] = {REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, - [IREG_NPXSx] = {REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXCx] = { REG_WORD, &cpu_state.npxc, REG_INTEGER, REG_PERMANENT}, + [IREG_NPXSx] = { REG_WORD, &cpu_state.npxs, REG_INTEGER, REG_PERMANENT}, - [IREG_flagsx] = {REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, - [IREG_eflagsx] = {REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, + [IREG_flagsx] = { REG_WORD, &cpu_state.flags, REG_INTEGER, REG_PERMANENT}, + [IREG_eflagsx] = { REG_WORD, &cpu_state.eflags, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_limit_low] = {REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_limit_low] = {REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_limit_low] = {REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_limit_low] = {REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_limit_low] = {REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_limit_low] = {REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_low] = { REG_DWORD, &cpu_state.seg_cs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_low] = { REG_DWORD, &cpu_state.seg_ds.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_low] = { REG_DWORD, &cpu_state.seg_es.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_low] = { REG_DWORD, &cpu_state.seg_fs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_low] = { REG_DWORD, &cpu_state.seg_gs.limit_low, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_low] = { REG_DWORD, &cpu_state.seg_ss.limit_low, REG_INTEGER, REG_PERMANENT}, - [IREG_CS_limit_high] = {REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_DS_limit_high] = {REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_ES_limit_high] = {REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_FS_limit_high] = {REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_GS_limit_high] = {REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, - [IREG_SS_limit_high] = {REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_CS_limit_high] = { REG_DWORD, &cpu_state.seg_cs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_DS_limit_high] = { REG_DWORD, &cpu_state.seg_ds.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_ES_limit_high] = { REG_DWORD, &cpu_state.seg_es.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_FS_limit_high] = { REG_DWORD, &cpu_state.seg_fs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_GS_limit_high] = { REG_DWORD, &cpu_state.seg_gs.limit_high, REG_INTEGER, REG_PERMANENT}, + [IREG_SS_limit_high] = { REG_DWORD, &cpu_state.seg_ss.limit_high, REG_INTEGER, REG_PERMANENT}, - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - [IREG_temp0] = {REG_DWORD, (void *)16, REG_INTEGER, REG_VOLATILE}, - [IREG_temp1] = {REG_DWORD, (void *)20, REG_INTEGER, REG_VOLATILE}, - [IREG_temp2] = {REG_DWORD, (void *)24, REG_INTEGER, REG_VOLATILE}, - [IREG_temp3] = {REG_DWORD, (void *)28, REG_INTEGER, REG_VOLATILE}, + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + [IREG_temp0] = { REG_DWORD, (void *) 16, REG_INTEGER, REG_VOLATILE }, + [IREG_temp1] = { REG_DWORD, (void *) 20, REG_INTEGER, REG_VOLATILE }, + [IREG_temp2] = { REG_DWORD, (void *) 24, REG_INTEGER, REG_VOLATILE }, + [IREG_temp3] = { REG_DWORD, (void *) 28, REG_INTEGER, REG_VOLATILE }, - [IREG_temp0d] = {REG_DOUBLE, (void *)40, REG_FP, REG_VOLATILE}, - [IREG_temp1d] = {REG_DOUBLE, (void *)48, REG_FP, REG_VOLATILE}, + [IREG_temp0d] = { REG_DOUBLE, (void *) 40, REG_FP, REG_VOLATILE }, + [IREG_temp1d] = { REG_DOUBLE, (void *) 48, REG_FP, REG_VOLATILE }, }; -void codegen_reg_mark_as_required(void) +void +codegen_reg_mark_as_required(void) { - int reg; + int reg; - for (reg = 0; reg < IREG_COUNT; reg++) - { - int last_version = reg_last_version[reg]; + for (reg = 0; reg < IREG_COUNT; reg++) { + int last_version = reg_last_version[reg]; - if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) - reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; - } + if (last_version > 0 && ireg_data[reg].is_volatile == REG_PERMANENT) + reg_version[reg][last_version].flags |= REG_FLAGS_REQUIRED; + } } -int reg_is_native_size(ir_reg_t ir_reg) +int +reg_is_native_size(ir_reg_t ir_reg) { - int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; - int requested_size = IREG_GET_SIZE(ir_reg.reg); + int native_size = ireg_data[IREG_GET_REG(ir_reg.reg)].native_size; + int requested_size = IREG_GET_SIZE(ir_reg.reg); - switch (native_size) - { - case REG_BYTE: case REG_FPU_ST_BYTE: - return (requested_size == IREG_SIZE_B); - case REG_WORD: - return (requested_size == IREG_SIZE_W); - case REG_DWORD: + switch (native_size) { + case REG_BYTE: + case REG_FPU_ST_BYTE: + return (requested_size == IREG_SIZE_B); + case REG_WORD: + return (requested_size == IREG_SIZE_W); + case REG_DWORD: + return (requested_size == IREG_SIZE_L); + case REG_QWORD: + case REG_FPU_ST_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_DOUBLE: + return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); + case REG_POINTER: + if (sizeof(void *) == 4) return (requested_size == IREG_SIZE_L); - case REG_QWORD: case REG_FPU_ST_QWORD: case REG_DOUBLE: case REG_FPU_ST_DOUBLE: - return ((requested_size == IREG_SIZE_D) || (requested_size == IREG_SIZE_Q)); - case REG_POINTER: - if (sizeof(void *) == 4) - return (requested_size == IREG_SIZE_L); - return (requested_size == IREG_SIZE_Q); + return (requested_size == IREG_SIZE_Q); - default: - fatal("get_reg_is_native_size: unknown native size %i\n", native_size); - } + default: + fatal("get_reg_is_native_size: unknown native size %i\n", native_size); + } - return 0; + return 0; } -void codegen_reg_reset(void) +void +codegen_reg_reset(void) { - int c; + int c; - host_reg_set.regs = _host_regs; - host_reg_set.dirty = _host_reg_dirty; - host_reg_set.reg_list = codegen_host_reg_list; - host_reg_set.locked = 0; - host_reg_set.nr_regs = CODEGEN_HOST_REGS; - host_fp_reg_set.regs = host_fp_regs; - host_fp_reg_set.dirty = host_fp_reg_dirty; - host_fp_reg_set.reg_list = codegen_host_fp_reg_list; - host_fp_reg_set.locked = 0; - host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; + host_reg_set.regs = _host_regs; + host_reg_set.dirty = _host_reg_dirty; + host_reg_set.reg_list = codegen_host_reg_list; + host_reg_set.locked = 0; + host_reg_set.nr_regs = CODEGEN_HOST_REGS; + host_fp_reg_set.regs = host_fp_regs; + host_fp_reg_set.dirty = host_fp_reg_dirty; + host_fp_reg_set.reg_list = codegen_host_fp_reg_list; + host_fp_reg_set.locked = 0; + host_fp_reg_set.nr_regs = CODEGEN_HOST_FP_REGS; - for (c = 0; c < IREG_COUNT; c++) - { - reg_last_version[c] = 0; - reg_version[c][0].refcount = 0; - } - for (c = 0; c < CODEGEN_HOST_REGS; c++) - { - host_reg_set.regs[c] = invalid_ir_reg; - host_reg_set.dirty[c] = 0; - } - for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) - { - host_fp_reg_set.regs[c] = invalid_ir_reg; - host_fp_reg_set.dirty[c] = 0; - } + for (c = 0; c < IREG_COUNT; c++) { + reg_last_version[c] = 0; + reg_version[c][0].refcount = 0; + } + for (c = 0; c < CODEGEN_HOST_REGS; c++) { + host_reg_set.regs[c] = invalid_ir_reg; + host_reg_set.dirty[c] = 0; + } + for (c = 0; c < CODEGEN_HOST_FP_REGS; c++) { + host_fp_reg_set.regs[c] = invalid_ir_reg; + host_fp_reg_set.dirty[c] = 0; + } - reg_dead_list = 0; - max_version_refcount = 0; + reg_dead_list = 0; + max_version_refcount = 0; } -static inline int ir_get_refcount(ir_reg_t ir_reg) +static inline int +ir_get_refcount(ir_reg_t ir_reg) { - return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; + return reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version].refcount; } -static inline host_reg_set_t *get_reg_set(ir_reg_t ir_reg) +static inline host_reg_set_t * +get_reg_set(ir_reg_t ir_reg) { - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) - return &host_reg_set; - else - return &host_fp_reg_set; + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type == REG_INTEGER) + return &host_reg_set; + else + return &host_fp_reg_set; } -static void codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, ir_reg_t ir_reg) +static void +codegen_reg_load(host_reg_set_t *reg_set, codeblock_t *block, int c, ir_reg_t ir_reg) { - switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) - { - case REG_WORD: + switch (ireg_data[IREG_GET_REG(ir_reg.reg)].native_size) { + case REG_WORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_WORD !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_16_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_16(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_DWORD: + case REG_DWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_DWORD !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_32_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_32(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_QWORD: + case REG_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_QWORD !REG_FP\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_64_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_64(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_POINTER: + case REG_POINTER: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_POINTER !REG_INTEGER\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_pointer_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_pointer(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_DOUBLE: + case REG_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_DOUBLE !REG_FP\n"); #endif - if ((uintptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) - codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t)ireg_data[IREG_GET_REG(ir_reg.reg)].p); - else - codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); - break; + if ((uintptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p < 256) + codegen_direct_read_double_stack(block, reg_set->reg_list[c].reg, (intptr_t) ireg_data[IREG_GET_REG(ir_reg.reg)].p); + else + codegen_direct_read_double(block, reg_set->reg_list[c].reg, ireg_data[IREG_GET_REG(ir_reg.reg)].p); + break; - case REG_FPU_ST_BYTE: + case REG_FPU_ST_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) - fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_INTEGER) + fatal("codegen_reg_load - REG_FPU_ST_BYTE !REG_INTEGER\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); - else - codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[ir_reg.reg & 7]); + else + codegen_direct_read_st_8(block, reg_set->reg_list[c].reg, &cpu_state.tag[0], ir_reg.reg & 7); + break; - case REG_FPU_ST_QWORD: + case REG_FPU_ST_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_QWORD !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); - else - codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[ir_reg.reg & 7]); + else + codegen_direct_read_st_64(block, reg_set->reg_list[c].reg, &cpu_state.MM[0], ir_reg.reg & 7); + break; - case REG_FPU_ST_DOUBLE: + case REG_FPU_ST_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) - fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); + if (ireg_data[IREG_GET_REG(ir_reg.reg)].type != REG_FP) + fatal("codegen_reg_load - REG_FPU_ST_DOUBLE !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); - else - codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_read_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[ir_reg.reg & 7]); + else + codegen_direct_read_st_double(block, reg_set->reg_list[c].reg, &cpu_state.ST[0], ir_reg.reg & 7); + break; - default: - fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, IREG_GET_REG(ir_reg.reg)); - } + default: + fatal("codegen_reg_load - native_size=%i reg=%i\n", ireg_data[IREG_GET_REG(ir_reg.reg)].native_size, IREG_GET_REG(ir_reg.reg)); + } - reg_set->regs[c] = ir_reg; + reg_set->regs[c] = ir_reg; } -static void codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, int c, int invalidate) +static void +codegen_reg_writeback(host_reg_set_t *reg_set, codeblock_t *block, int c, int invalidate) { - int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); - void *p = ireg_data[ir_reg].p; + int ir_reg = IREG_GET_REG(reg_set->regs[c].reg); + void *p = ireg_data[ir_reg].p; - if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && - ireg_data[ir_reg].is_volatile) - return; + if (!reg_version[ir_reg][reg_set->regs[c].version].refcount && ireg_data[ir_reg].is_volatile) + return; - switch (ireg_data[ir_reg].native_size) - { - case REG_BYTE: + switch (ireg_data[ir_reg].native_size) { + case REG_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_BYTE %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_BYTE !REG_INTEGER\n"); + if ((uintptr_t) p < 256) + fatal("codegen_reg_writeback - REG_BYTE %p\n", p); #endif - codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_8(block, p, reg_set->reg_list[c].reg); + break; - case REG_WORD: + case REG_WORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_WORD %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_WORD !REG_INTEGER\n"); + if ((uintptr_t) p < 256) + fatal("codegen_reg_writeback - REG_WORD %p\n", p); #endif - codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_16(block, p, reg_set->reg_list[c].reg); + break; - case REG_DWORD: + case REG_DWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_DWORD !REG_INTEGER\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_32_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t) p < 256) + codegen_direct_write_32_stack(block, (intptr_t) p, reg_set->reg_list[c].reg); + else + codegen_direct_write_32(block, p, reg_set->reg_list[c].reg); + break; - case REG_QWORD: + case REG_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_QWORD !REG_FP\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_64_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t) p < 256) + codegen_direct_write_64_stack(block, (intptr_t) p, reg_set->reg_list[c].reg); + else + codegen_direct_write_64(block, p, reg_set->reg_list[c].reg); + break; - case REG_POINTER: + case REG_POINTER: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); - if ((uintptr_t)p < 256) - fatal("codegen_reg_writeback - REG_POINTER %p\n", p); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_POINTER !REG_INTEGER\n"); + if ((uintptr_t) p < 256) + fatal("codegen_reg_writeback - REG_POINTER %p\n", p); #endif - codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); - break; + codegen_direct_write_ptr(block, p, reg_set->reg_list[c].reg); + break; - case REG_DOUBLE: + case REG_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_DOUBLE !REG_FP\n"); #endif - if ((uintptr_t)p < 256) - codegen_direct_write_double_stack(block, (intptr_t)p, reg_set->reg_list[c].reg); - else - codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); - break; + if ((uintptr_t) p < 256) + codegen_direct_write_double_stack(block, (intptr_t) p, reg_set->reg_list[c].reg); + else + codegen_direct_write_double(block, p, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_BYTE: + case REG_FPU_ST_BYTE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_INTEGER) - fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); + if (ireg_data[ir_reg].type != REG_INTEGER) + fatal("codegen_reg_writeback - REG_FPU_ST_BYTE !REG_INTEGER\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_8(block, &cpu_state.tag[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_8(block, &cpu_state.tag[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_QWORD: + case REG_FPU_ST_QWORD: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_QWORD !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_64(block, &cpu_state.MM[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_64(block, &cpu_state.MM[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - case REG_FPU_ST_DOUBLE: + case REG_FPU_ST_DOUBLE: #ifndef RELEASE_BUILD - if (ireg_data[ir_reg].type != REG_FP) - fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); + if (ireg_data[ir_reg].type != REG_FP) + fatal("codegen_reg_writeback - REG_FPU_ST_DOUBLE !REG_FP\n"); #endif - if (block->flags & CODEBLOCK_STATIC_TOP) - codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); - else - codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); - break; + if (block->flags & CODEBLOCK_STATIC_TOP) + codegen_direct_write_double(block, &cpu_state.ST[reg_set->regs[c].reg & 7], reg_set->reg_list[c].reg); + else + codegen_direct_write_st_double(block, &cpu_state.ST[0], reg_set->regs[c].reg & 7, reg_set->reg_list[c].reg); + break; - default: - fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); - } + default: + fatal("codegen_reg_flush - native_size=%i\n", ireg_data[ir_reg].native_size); + } - if (invalidate) - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + if (invalidate) + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } #ifdef CODEGEN_BACKEND_HAS_MOV_IMM -void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data) +void +codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data) { - int reg_idx = IREG_GET_REG(ir_reg.reg); - void *p = ireg_data[reg_idx].p; + int reg_idx = IREG_GET_REG(ir_reg.reg); + void *p = ireg_data[reg_idx].p; - switch (ireg_data[reg_idx].native_size) - { - case REG_BYTE: -#ifndef RELEASE_BUILD - if ((uintptr_t)p < 256) - fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); -#endif - codegen_direct_write_8_imm(block, p, imm_data); - break; + switch (ireg_data[reg_idx].native_size) { + case REG_BYTE: +# ifndef RELEASE_BUILD + if ((uintptr_t) p < 256) + fatal("codegen_reg_write_imm - REG_BYTE %p\n", p); +# endif + codegen_direct_write_8_imm(block, p, imm_data); + break; - case REG_WORD: -#ifndef RELEASE_BUILD - if ((uintptr_t)p < 256) - fatal("codegen_reg_write_imm - REG_WORD %p\n", p); -#endif - codegen_direct_write_16_imm(block, p, imm_data); - break; + case REG_WORD: +# ifndef RELEASE_BUILD + if ((uintptr_t) p < 256) + fatal("codegen_reg_write_imm - REG_WORD %p\n", p); +# endif + codegen_direct_write_16_imm(block, p, imm_data); + break; - case REG_DWORD: - if ((uintptr_t)p < 256) - codegen_direct_write_32_imm_stack(block, (int)((uintptr_t) p), imm_data); - else - codegen_direct_write_32_imm(block, p, imm_data); - break; + case REG_DWORD: + if ((uintptr_t) p < 256) + codegen_direct_write_32_imm_stack(block, (int) ((uintptr_t) p), imm_data); + else + codegen_direct_write_32_imm(block, p, imm_data); + break; - case REG_POINTER: - case REG_QWORD: - case REG_DOUBLE: - case REG_FPU_ST_BYTE: - case REG_FPU_ST_QWORD: - case REG_FPU_ST_DOUBLE: - default: - fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); - } + case REG_POINTER: + case REG_QWORD: + case REG_DOUBLE: + case REG_FPU_ST_BYTE: + case REG_FPU_ST_QWORD: + case REG_FPU_ST_DOUBLE: + default: + fatal("codegen_reg_write_imm - native_size=%i\n", ireg_data[reg_idx].native_size); + } } #endif -static void alloc_reg(ir_reg_t ir_reg) +static void +alloc_reg(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; - for (c = 0; c < nr_regs; c++) - { - if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { + for (c = 0; c < nr_regs; c++) { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { #ifndef RELEASE_BUILD - if (reg_set->regs[c].version != ir_reg.version) - fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); + if (reg_set->regs[c].version != ir_reg.version) + fatal("alloc_reg - host_regs[c].version != ir_reg.version %i %p %p %i %i\n", c, reg_set, &host_reg_set, reg_set->regs[c].reg, ir_reg.reg); #endif + reg_set->locked |= (1 << c); + return; + } + } +} + +static void +alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) +{ + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; + int c; + + for (c = 0; c < nr_regs; c++) { + if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version == ir_reg.version) { + reg_set->locked |= (1 << c); + } else { + /*The immediate prior version may have been + optimised out, so search backwards to find the + last valid version*/ + int prev_version = ir_reg.version - 1; + while (prev_version >= 0) { + reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + + if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) { reg_set->locked |= (1 << c); return; + } + prev_version--; } + fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); + } + return; } + } } -static void alloc_dest_reg(ir_reg_t ir_reg, int dest_reference) +void +codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int nr_regs = (reg_set == &host_reg_set) ? CODEGEN_HOST_REGS : CODEGEN_HOST_FP_REGS; - int c; + int dest_reference = 0; - for (c = 0; c < nr_regs; c++) - { - if (IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { - if (reg_set->regs[c].version == ir_reg.version) - { - reg_set->locked |= (1 << c); - } - else - { - /*The immediate prior version may have been - optimised out, so search backwards to find the - last valid version*/ - int prev_version = ir_reg.version-1; - while (prev_version >= 0) - { - reg_version_t *regv = ®_version[IREG_GET_REG(reg_set->regs[c].reg)][prev_version]; + host_reg_set.locked = 0; + host_fp_reg_set.locked = 0; - if (!(regv->flags & REG_FLAGS_DEAD) && regv->refcount == dest_reference) - { - reg_set->locked |= (1 << c); - return; - } - prev_version--; - } - fatal("codegen_reg_alloc_register - host_regs[c].version != dest_reg_a.version %i,%i %i\n", reg_set->regs[c].version, ir_reg.version, dest_reference); - } - return; - } - } + if (!ir_reg_is_invalid(dest_reg_a)) { + if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version - 1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version - 1) + dest_reference++; + if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version - 1) + dest_reference++; + } + if (!ir_reg_is_invalid(src_reg_a)) + alloc_reg(src_reg_a); + if (!ir_reg_is_invalid(src_reg_b)) + alloc_reg(src_reg_b); + if (!ir_reg_is_invalid(src_reg_c)) + alloc_reg(src_reg_c); + if (!ir_reg_is_invalid(dest_reg_a)) + alloc_dest_reg(dest_reg_a, dest_reference); } -void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c) +ir_host_reg_t +codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) { - int dest_reference = 0; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - host_reg_set.locked = 0; - host_fp_reg_set.locked = 0; + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) + break; - if (!ir_reg_is_invalid(dest_reg_a)) - { - if (!ir_reg_is_invalid(src_reg_a) && IREG_GET_REG(src_reg_a.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_a.version == dest_reg_a.version-1) - dest_reference++; - if (!ir_reg_is_invalid(src_reg_b) && IREG_GET_REG(src_reg_b.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_b.version == dest_reg_a.version-1) - dest_reference++; - if (!ir_reg_is_invalid(src_reg_c) && IREG_GET_REG(src_reg_c.reg) == IREG_GET_REG(dest_reg_a.reg) && src_reg_c.version == dest_reg_a.version-1) - dest_reference++; + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version <= ir_reg.version) { + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; + break; } - if (!ir_reg_is_invalid(src_reg_a)) - alloc_reg(src_reg_a); - if (!ir_reg_is_invalid(src_reg_b)) - alloc_reg(src_reg_b); - if (!ir_reg_is_invalid(src_reg_c)) - alloc_reg(src_reg_c); - if (!ir_reg_is_invalid(dest_reg_a)) - alloc_dest_reg(dest_reg_a, dest_reference); + +#ifndef RELEASE_BUILD + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) + fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); +#endif + } + + if (c == reg_set->nr_regs) { + /*No unused registers. Search for an unlocked register with no pending reads*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && !ir_get_refcount(reg_set->regs[c])) + break; + } + if (c == reg_set->nr_regs) { + /*Search for any unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c))) + break; + } +#ifndef RELEASE_BUILD + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_read_reg - out of registers\n"); +#endif + } + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); + codegen_reg_load(reg_set, block, c, ir_reg); + reg_set->locked |= (1 << c); + reg_set->dirty[c] = 0; + } + + reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; +#ifndef RELEASE_BUILD + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t) -1) + fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); +#endif + + if (host_reg_idx) + *host_reg_idx = c; + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } -ir_host_reg_t codegen_reg_alloc_read_reg(codeblock_t *block, ir_reg_t ir_reg, int *host_reg_idx) +ir_host_reg_t +codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - /*Search for required register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version == ir_reg.version) - break; + if (!reg_is_native_size(ir_reg)) { + /*Read in parent register so we can do partial accesses to it*/ + ir_reg_t parent_reg; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_set->regs[c].version <= ir_reg.version) - { - reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount++; - break; - } + parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; + parent_reg.version = ir_reg.version - 1; + reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; + + codegen_reg_alloc_read_reg(block, parent_reg, &c); #ifndef RELEASE_BUILD - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg) && reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount) - fatal("codegen_reg_alloc_read_reg - version mismatch!\n"); -#endif - } - - if (c == reg_set->nr_regs) - { - /*No unused registers. Search for an unlocked register with no pending reads*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!(reg_set->locked & (1 << c)) && IREG_GET_REG(reg_set->regs[c].reg) != IREG_INVALID && !ir_get_refcount(reg_set->regs[c])) - break; - } - if (c == reg_set->nr_regs) - { - /*Search for any unlocked register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!(reg_set->locked & (1 << c))) - break; - } -#ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_read_reg - out of registers\n"); -#endif - } - if (reg_set->dirty[c]) - codegen_reg_writeback(reg_set, block, c, 1); - codegen_reg_load(reg_set, block, c, ir_reg); - reg_set->locked |= (1 << c); - reg_set->dirty[c] = 0; - } - - reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount--; -#ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount == (uint8_t)-1) - fatal("codegen_reg_alloc_read_reg - refcount < 0\n"); + if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version - 1) + fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, + reg_set->regs[c].reg, reg_set->regs[c].version, + ir_reg.reg, ir_reg.version); #endif - if (host_reg_idx) - *host_reg_idx = c; - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); -} - -ir_host_reg_t codegen_reg_alloc_write_reg(codeblock_t *block, ir_reg_t ir_reg) -{ - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; - - if (!reg_is_native_size(ir_reg)) - { - /*Read in parent register so we can do partial accesses to it*/ - ir_reg_t parent_reg; - - parent_reg.reg = IREG_GET_REG(ir_reg.reg) | IREG_SIZE_L; - parent_reg.version = ir_reg.version - 1; - reg_version[IREG_GET_REG(ir_reg.reg)][ir_reg.version - 1].refcount++; - - codegen_reg_alloc_read_reg(block, parent_reg, &c); - -#ifndef RELEASE_BUILD - if (IREG_GET_REG(reg_set->regs[c].reg) != IREG_GET_REG(ir_reg.reg) || reg_set->regs[c].version > ir_reg.version-1) - fatal("codegen_reg_alloc_write_reg sub_reg - doesn't match %i %02x.%i %02x.%i\n", c, - reg_set->regs[c].reg,reg_set->regs[c].version, - ir_reg.reg,ir_reg.version); -#endif - - reg_set->regs[c].reg = ir_reg.reg; - reg_set->regs[c].version = ir_reg.version; - reg_set->dirty[c] = 1; - return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); - } - - /*Search for previous version in host register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { - if (reg_set->regs[c].version <= ir_reg.version-1) - { -#ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) - fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); -#endif - break; - } - } - } - - if (c == reg_set->nr_regs) - { - /*Search for unused registers*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (ir_reg_is_invalid(reg_set->regs[c])) - break; - } - - if (c == reg_set->nr_regs) - { - /*No unused registers. Search for an unlocked register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!(reg_set->locked & (1 << c))) - break; - } -#ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_alloc_write_reg - out of registers\n"); -#endif - if (reg_set->dirty[c]) - codegen_reg_writeback(reg_set, block, c, 1); - } - } - - reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].reg = ir_reg.reg; reg_set->regs[c].version = ir_reg.version; - reg_set->dirty[c] = 1; + reg_set->dirty[c] = 1; return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); + } + + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version <= ir_reg.version - 1) { +#ifndef RELEASE_BUILD + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); +#endif + break; + } + } + } + + if (c == reg_set->nr_regs) { + /*Search for unused registers*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (ir_reg_is_invalid(reg_set->regs[c])) + break; + } + + if (c == reg_set->nr_regs) { + /*No unused registers. Search for an unlocked register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!(reg_set->locked & (1 << c))) + break; + } +#ifndef RELEASE_BUILD + if (c == reg_set->nr_regs) + fatal("codegen_reg_alloc_write_reg - out of registers\n"); +#endif + if (reg_set->dirty[c]) + codegen_reg_writeback(reg_set, block, c, 1); + } + } + + reg_set->regs[c].reg = ir_reg.reg; + reg_set->regs[c].version = ir_reg.version; + reg_set->dirty[c] = 1; + return reg_set->reg_list[c].reg | IREG_GET_SIZE(ir_reg.reg); } #ifdef CODEGEN_BACKEND_HAS_MOV_IMM -int codegen_reg_is_loaded(ir_reg_t ir_reg) +int +codegen_reg_is_loaded(ir_reg_t ir_reg) { - host_reg_set_t *reg_set = get_reg_set(ir_reg); - int c; + host_reg_set_t *reg_set = get_reg_set(ir_reg); + int c; - /*Search for previous version in host register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) - { - if (reg_set->regs[c].version <= ir_reg.version-1) - { + /*Search for previous version in host register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(ir_reg.reg)) { + if (reg_set->regs[c].version <= ir_reg.version - 1) { +# ifndef RELEASE_BUILD + if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) + fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); +# endif + return 1; + } + } + } + return 0; +} +#endif + +void +codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) +{ + host_reg_set_t *reg_set = get_reg_set(src); + int c; + int target; + + // pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); + /*Search for required register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) + break; + } #ifndef RELEASE_BUILD - if (reg_version[IREG_GET_REG(reg_set->regs[c].reg)][reg_set->regs[c].version].refcount != 0) - fatal("codegen_reg_alloc_write_reg - previous version refcount != 0\n"); -#endif - return 1; - } - } - } - return 0; -} + if (c == reg_set->nr_regs) + fatal("codegen_reg_rename: Can't find register to rename\n"); #endif + target = c; + if (reg_set->dirty[target]) + codegen_reg_writeback(reg_set, block, target, 0); + reg_set->regs[target] = dst; + reg_set->dirty[target] = 1; + // pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); -void codegen_reg_rename(codeblock_t *block, ir_reg_t src, ir_reg_t dst) -{ - host_reg_set_t *reg_set = get_reg_set(src); - int c; - int target; - -// pclog("rename: %i.%i -> %i.%i\n", src.reg,src.version, dst.reg, dst.version); - /*Search for required register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(src.reg) && reg_set->regs[c].version == src.version) - break; - } -#ifndef RELEASE_BUILD - if (c == reg_set->nr_regs) - fatal("codegen_reg_rename: Can't find register to rename\n"); -#endif - target = c; - if (reg_set->dirty[target]) - codegen_reg_writeback(reg_set, block, target, 0); - reg_set->regs[target] = dst; - reg_set->dirty[target] = 1; -// pclog("renamed reg %i dest=%i.%i\n", target, dst.reg, dst.version); - - /*Invalidate any stale copies of the dest register*/ - for (c = 0; c < reg_set->nr_regs; c++) - { - if (c == target) - continue; - if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) - { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + /*Invalidate any stale copies of the dest register*/ + for (c = 0; c < reg_set->nr_regs; c++) { + if (c == target) + continue; + if (!ir_reg_is_invalid(reg_set->regs[c]) && IREG_GET_REG(reg_set->regs[c].reg) == IREG_GET_REG(dst.reg)) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; } + } } -void codegen_reg_flush(ir_data_t *ir, codeblock_t *block) +void +codegen_reg_flush(ir_data_t *ir, codeblock_t *block) { - host_reg_set_t *reg_set; - int c; + host_reg_set_t *reg_set; + int c; - reg_set = &host_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 0); - } - if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) - { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 0); } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } - reg_set = &host_fp_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 0); - } - if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) - { - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; - } + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 0); } + if (reg_set->reg_list[c].flags & HOST_REG_FLAG_VOLATILE) { + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } + } } -void codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) +void +codegen_reg_flush_invalidate(ir_data_t *ir, codeblock_t *block) { - host_reg_set_t *reg_set; - int c; + host_reg_set_t *reg_set; + int c; - reg_set = &host_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 1); - } - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + reg_set = &host_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 1); } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } - reg_set = &host_fp_reg_set; - for (c = 0; c < reg_set->nr_regs; c++) - { - if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) - { - codegen_reg_writeback(reg_set, block, c, 1); - } - reg_set->regs[c] = invalid_ir_reg; - reg_set->dirty[c] = 0; + reg_set = &host_fp_reg_set; + for (c = 0; c < reg_set->nr_regs; c++) { + if (!ir_reg_is_invalid(reg_set->regs[c]) && reg_set->dirty[c]) { + codegen_reg_writeback(reg_set, block, c, 1); } + reg_set->regs[c] = invalid_ir_reg; + reg_set->dirty[c] = 0; + } } /*Process dead register list, and optimise out register versions and uOPs where possible*/ -void codegen_reg_process_dead_list(ir_data_t *ir) +void +codegen_reg_process_dead_list(ir_data_t *ir) { - while (reg_dead_list) - { - int version = reg_dead_list & 0xff; - int reg = reg_dead_list >> 8; - reg_version_t *regv = ®_version[reg][version]; - uop_t *uop = &ir->uops[regv->parent_uop]; + while (reg_dead_list) { + int version = reg_dead_list & 0xff; + int reg = reg_dead_list >> 8; + reg_version_t *regv = ®_version[reg][version]; + uop_t *uop = &ir->uops[regv->parent_uop]; - /*Barrier uOPs should be preserved*/ - if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) - { - uop->type = UOP_INVALID; - /*Adjust refcounts on source registers. If these drop to - zero then those registers can be considered for removal*/ - if (uop->src_reg_a.reg != IREG_INVALID) - { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); - } - if (uop->src_reg_b.reg != IREG_INVALID) - { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); - } - if (uop->src_reg_c.reg != IREG_INVALID) - { - reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; - src_regv->refcount--; - if (!src_regv->refcount) - add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); - } - regv->flags |= REG_FLAGS_DEAD; - } - - reg_dead_list = regv->next; + /*Barrier uOPs should be preserved*/ + if (!(uop->type & (UOP_TYPE_BARRIER | UOP_TYPE_ORDER_BARRIER))) { + uop->type = UOP_INVALID; + /*Adjust refcounts on source registers. If these drop to + zero then those registers can be considered for removal*/ + if (uop->src_reg_a.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_a.reg)][uop->src_reg_a.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_a.reg), uop->src_reg_a.version); + } + if (uop->src_reg_b.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_b.reg)][uop->src_reg_b.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_b.reg), uop->src_reg_b.version); + } + if (uop->src_reg_c.reg != IREG_INVALID) { + reg_version_t *src_regv = ®_version[IREG_GET_REG(uop->src_reg_c.reg)][uop->src_reg_c.version]; + src_regv->refcount--; + if (!src_regv->refcount) + add_to_dead_list(src_regv, IREG_GET_REG(uop->src_reg_c.reg), uop->src_reg_c.version); + } + regv->flags |= REG_FLAGS_DEAD; } + + reg_dead_list = regv->next; + } } diff --git a/src/codegen_new/codegen_reg.h b/src/codegen_new/codegen_reg.h index fb8789474..c106349f5 100644 --- a/src/codegen_new/codegen_reg.h +++ b/src/codegen_new/codegen_reg.h @@ -1,276 +1,278 @@ #ifndef _CODEGEN_REG_H_ #define _CODEGEN_REG_H_ -#define IREG_REG_MASK 0xff -#define IREG_SIZE_SHIFT 8 -#define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT) +#define IREG_REG_MASK 0xff +#define IREG_SIZE_SHIFT 8 +#define IREG_SIZE_MASK (7 << IREG_SIZE_SHIFT) -#define IREG_GET_REG(reg) ((reg) & IREG_REG_MASK) -#define IREG_GET_SIZE(reg) ((reg) & IREG_SIZE_MASK) +#define IREG_GET_REG(reg) ((reg) &IREG_REG_MASK) +#define IREG_GET_SIZE(reg) ((reg) &IREG_SIZE_MASK) -#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) -#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) -#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) -#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) -#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) -#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) +#define IREG_SIZE_L (0 << IREG_SIZE_SHIFT) +#define IREG_SIZE_W (1 << IREG_SIZE_SHIFT) +#define IREG_SIZE_B (2 << IREG_SIZE_SHIFT) +#define IREG_SIZE_BH (3 << IREG_SIZE_SHIFT) +#define IREG_SIZE_D (4 << IREG_SIZE_SHIFT) +#define IREG_SIZE_Q (5 << IREG_SIZE_SHIFT) -enum -{ - IREG_EAX = 0, - IREG_ECX = 1, - IREG_EDX = 2, - IREG_EBX = 3, - IREG_ESP = 4, - IREG_EBP = 5, - IREG_ESI = 6, - IREG_EDI = 7, +enum { + IREG_EAX = 0, + IREG_ECX = 1, + IREG_EDX = 2, + IREG_EBX = 3, + IREG_ESP = 4, + IREG_EBP = 5, + IREG_ESI = 6, + IREG_EDI = 7, - IREG_flags_op = 8, - IREG_flags_res = 9, - IREG_flags_op1 = 10, - IREG_flags_op2 = 11, + IREG_flags_op = 8, + IREG_flags_res = 9, + IREG_flags_op1 = 10, + IREG_flags_op2 = 11, - IREG_pc = 12, - IREG_oldpc = 13, + IREG_pc = 12, + IREG_oldpc = 13, - IREG_eaaddr = 14, - IREG_ea_seg = 15, - IREG_op32 = 16, - IREG_ssegsx = 17, + IREG_eaaddr = 14, + IREG_ea_seg = 15, + IREG_op32 = 16, + IREG_ssegsx = 17, - IREG_rm_mod_reg = 18, + IREG_rm_mod_reg = 18, - IREG_acycs = 19, - IREG_cycles = 20, + IREG_acycs = 19, + IREG_cycles = 20, - IREG_CS_base = 21, - IREG_DS_base = 22, - IREG_ES_base = 23, - IREG_FS_base = 24, - IREG_GS_base = 25, - IREG_SS_base = 26, + IREG_CS_base = 21, + IREG_DS_base = 22, + IREG_ES_base = 23, + IREG_FS_base = 24, + IREG_GS_base = 25, + IREG_SS_base = 26, - IREG_CS_seg = 27, - IREG_DS_seg = 28, - IREG_ES_seg = 29, - IREG_FS_seg = 30, - IREG_GS_seg = 31, - IREG_SS_seg = 32, + IREG_CS_seg = 27, + IREG_DS_seg = 28, + IREG_ES_seg = 29, + IREG_FS_seg = 30, + IREG_GS_seg = 31, + IREG_SS_seg = 32, - /*Temporary registers are stored on the stack, and are not guaranteed to - be preserved across uOPs. They will not be written back if they will - not be read again.*/ - IREG_temp0 = 33, - IREG_temp1 = 34, - IREG_temp2 = 35, - IREG_temp3 = 36, + /*Temporary registers are stored on the stack, and are not guaranteed to + be preserved across uOPs. They will not be written back if they will + not be read again.*/ + IREG_temp0 = 33, + IREG_temp1 = 34, + IREG_temp2 = 35, + IREG_temp3 = 36, - IREG_FPU_TOP = 37, + IREG_FPU_TOP = 37, - IREG_temp0d = 38, - IREG_temp1d = 39, + IREG_temp0d = 38, + IREG_temp1d = 39, - /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() - to access. - When CODEBLOCK_STATIC_TOP is set, the physical register number will be - used directly to index the stack. When it is clear, the difference - between the current value of TOP and the value when the block was - first compiled will be added to adjust for any changes in TOP.*/ - IREG_ST0 = 40, - IREG_ST1 = 41, - IREG_ST2 = 42, - IREG_ST3 = 43, - IREG_ST4 = 44, - IREG_ST5 = 45, - IREG_ST6 = 46, - IREG_ST7 = 47, + /*FPU stack registers are physical registers. Use IREG_ST() / IREG_tag() + to access. + When CODEBLOCK_STATIC_TOP is set, the physical register number will be + used directly to index the stack. When it is clear, the difference + between the current value of TOP and the value when the block was + first compiled will be added to adjust for any changes in TOP.*/ + IREG_ST0 = 40, + IREG_ST1 = 41, + IREG_ST2 = 42, + IREG_ST3 = 43, + IREG_ST4 = 44, + IREG_ST5 = 45, + IREG_ST6 = 46, + IREG_ST7 = 47, - IREG_tag0 = 48, - IREG_tag1 = 49, - IREG_tag2 = 50, - IREG_tag3 = 51, - IREG_tag4 = 52, - IREG_tag5 = 53, - IREG_tag6 = 54, - IREG_tag7 = 55, + IREG_tag0 = 48, + IREG_tag1 = 49, + IREG_tag2 = 50, + IREG_tag3 = 51, + IREG_tag4 = 52, + IREG_tag5 = 53, + IREG_tag6 = 54, + IREG_tag7 = 55, - IREG_ST0_i64 = 56, - IREG_ST1_i64 = 57, - IREG_ST2_i64 = 58, - IREG_ST3_i64 = 59, - IREG_ST4_i64 = 60, - IREG_ST5_i64 = 61, - IREG_ST6_i64 = 62, - IREG_ST7_i64 = 63, + IREG_ST0_i64 = 56, + IREG_ST1_i64 = 57, + IREG_ST2_i64 = 58, + IREG_ST3_i64 = 59, + IREG_ST4_i64 = 60, + IREG_ST5_i64 = 61, + IREG_ST6_i64 = 62, + IREG_ST7_i64 = 63, - IREG_MM0x = 64, - IREG_MM1x = 65, - IREG_MM2x = 66, - IREG_MM3x = 67, - IREG_MM4x = 68, - IREG_MM5x = 69, - IREG_MM6x = 70, - IREG_MM7x = 71, + IREG_MM0x = 64, + IREG_MM1x = 65, + IREG_MM2x = 66, + IREG_MM3x = 67, + IREG_MM4x = 68, + IREG_MM5x = 69, + IREG_MM6x = 70, + IREG_MM7x = 71, - IREG_NPXCx = 72, - IREG_NPXSx = 73, + IREG_NPXCx = 72, + IREG_NPXSx = 73, - IREG_flagsx = 74, - IREG_eflagsx = 75, + IREG_flagsx = 74, + IREG_eflagsx = 75, - IREG_CS_limit_low = 76, - IREG_DS_limit_low = 77, - IREG_ES_limit_low = 78, - IREG_FS_limit_low = 79, - IREG_GS_limit_low = 80, - IREG_SS_limit_low = 81, + IREG_CS_limit_low = 76, + IREG_DS_limit_low = 77, + IREG_ES_limit_low = 78, + IREG_FS_limit_low = 79, + IREG_GS_limit_low = 80, + IREG_SS_limit_low = 81, - IREG_CS_limit_high = 82, - IREG_DS_limit_high = 83, - IREG_ES_limit_high = 84, - IREG_FS_limit_high = 85, - IREG_GS_limit_high = 86, - IREG_SS_limit_high = 87, + IREG_CS_limit_high = 82, + IREG_DS_limit_high = 83, + IREG_ES_limit_high = 84, + IREG_FS_limit_high = 85, + IREG_GS_limit_high = 86, + IREG_SS_limit_high = 87, - IREG_COUNT = 88, + IREG_COUNT = 88, - IREG_INVALID = 255, + IREG_INVALID = 255, - IREG_AX = IREG_EAX + IREG_SIZE_W, - IREG_CX = IREG_ECX + IREG_SIZE_W, - IREG_DX = IREG_EDX + IREG_SIZE_W, - IREG_BX = IREG_EBX + IREG_SIZE_W, - IREG_SP = IREG_ESP + IREG_SIZE_W, - IREG_BP = IREG_EBP + IREG_SIZE_W, - IREG_SI = IREG_ESI + IREG_SIZE_W, - IREG_DI = IREG_EDI + IREG_SIZE_W, + IREG_AX = IREG_EAX + IREG_SIZE_W, + IREG_CX = IREG_ECX + IREG_SIZE_W, + IREG_DX = IREG_EDX + IREG_SIZE_W, + IREG_BX = IREG_EBX + IREG_SIZE_W, + IREG_SP = IREG_ESP + IREG_SIZE_W, + IREG_BP = IREG_EBP + IREG_SIZE_W, + IREG_SI = IREG_ESI + IREG_SIZE_W, + IREG_DI = IREG_EDI + IREG_SIZE_W, - IREG_AL = IREG_EAX + IREG_SIZE_B, - IREG_CL = IREG_ECX + IREG_SIZE_B, - IREG_DL = IREG_EDX + IREG_SIZE_B, - IREG_BL = IREG_EBX + IREG_SIZE_B, + IREG_AL = IREG_EAX + IREG_SIZE_B, + IREG_CL = IREG_ECX + IREG_SIZE_B, + IREG_DL = IREG_EDX + IREG_SIZE_B, + IREG_BL = IREG_EBX + IREG_SIZE_B, - IREG_AH = IREG_EAX + IREG_SIZE_BH, - IREG_CH = IREG_ECX + IREG_SIZE_BH, - IREG_DH = IREG_EDX + IREG_SIZE_BH, - IREG_BH = IREG_EBX + IREG_SIZE_BH, + IREG_AH = IREG_EAX + IREG_SIZE_BH, + IREG_CH = IREG_ECX + IREG_SIZE_BH, + IREG_DH = IREG_EDX + IREG_SIZE_BH, + IREG_BH = IREG_EBX + IREG_SIZE_BH, - IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, - IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, - IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, + IREG_flags_res_W = IREG_flags_res + IREG_SIZE_W, + IREG_flags_op1_W = IREG_flags_op1 + IREG_SIZE_W, + IREG_flags_op2_W = IREG_flags_op2 + IREG_SIZE_W, - IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, - IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, - IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, + IREG_flags_res_B = IREG_flags_res + IREG_SIZE_B, + IREG_flags_op1_B = IREG_flags_op1 + IREG_SIZE_B, + IREG_flags_op2_B = IREG_flags_op2 + IREG_SIZE_B, - IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, - IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, - IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, - IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, + IREG_temp0_W = IREG_temp0 + IREG_SIZE_W, + IREG_temp1_W = IREG_temp1 + IREG_SIZE_W, + IREG_temp2_W = IREG_temp2 + IREG_SIZE_W, + IREG_temp3_W = IREG_temp3 + IREG_SIZE_W, - IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, - IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, - IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, - IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, + IREG_temp0_B = IREG_temp0 + IREG_SIZE_B, + IREG_temp1_B = IREG_temp1 + IREG_SIZE_B, + IREG_temp2_B = IREG_temp2 + IREG_SIZE_B, + IREG_temp3_B = IREG_temp3 + IREG_SIZE_B, - IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, - IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, + IREG_temp0_D = IREG_temp0d + IREG_SIZE_D, + IREG_temp1_D = IREG_temp1d + IREG_SIZE_D, - IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, - IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, + IREG_temp0_Q = IREG_temp0d + IREG_SIZE_Q, + IREG_temp1_Q = IREG_temp1d + IREG_SIZE_Q, - IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, + IREG_eaaddr_W = IREG_eaaddr + IREG_SIZE_W, - IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, - IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W, - IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, - IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, - IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, - IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, + IREG_CS_seg_W = IREG_CS_seg + IREG_SIZE_W, + IREG_DS_seg_W = IREG_DS_seg + IREG_SIZE_W, + IREG_ES_seg_W = IREG_ES_seg + IREG_SIZE_W, + IREG_FS_seg_W = IREG_FS_seg + IREG_SIZE_W, + IREG_GS_seg_W = IREG_GS_seg + IREG_SIZE_W, + IREG_SS_seg_W = IREG_SS_seg + IREG_SIZE_W, - IREG_MM0 = IREG_MM0x + IREG_SIZE_Q, - IREG_MM1 = IREG_MM1x + IREG_SIZE_Q, - IREG_MM2 = IREG_MM2x + IREG_SIZE_Q, - IREG_MM3 = IREG_MM3x + IREG_SIZE_Q, - IREG_MM4 = IREG_MM4x + IREG_SIZE_Q, - IREG_MM5 = IREG_MM5x + IREG_SIZE_Q, - IREG_MM6 = IREG_MM6x + IREG_SIZE_Q, - IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, + IREG_MM0 = IREG_MM0x + IREG_SIZE_Q, + IREG_MM1 = IREG_MM1x + IREG_SIZE_Q, + IREG_MM2 = IREG_MM2x + IREG_SIZE_Q, + IREG_MM3 = IREG_MM3x + IREG_SIZE_Q, + IREG_MM4 = IREG_MM4x + IREG_SIZE_Q, + IREG_MM5 = IREG_MM5x + IREG_SIZE_Q, + IREG_MM6 = IREG_MM6x + IREG_SIZE_Q, + IREG_MM7 = IREG_MM7x + IREG_SIZE_Q, - IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, - IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, + IREG_NPXC = IREG_NPXCx + IREG_SIZE_W, + IREG_NPXS = IREG_NPXSx + IREG_SIZE_W, - IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, + IREG_ssegs = IREG_ssegsx + IREG_SIZE_B, - IREG_flags = IREG_flagsx + IREG_SIZE_W, - IREG_eflags = IREG_eflagsx + IREG_SIZE_W + IREG_flags = IREG_flagsx + IREG_SIZE_W, + IREG_eflags = IREG_eflagsx + IREG_SIZE_W }; -#define IREG_8(reg) (((reg) & 4) ? (((reg) & 3) + IREG_AH) : ((reg) + IREG_AL)) -#define IREG_16(reg) ((reg) + IREG_AX) -#define IREG_32(reg) ((reg) + IREG_EAX) +#define IREG_8(reg) (((reg) &4) ? (((reg) &3) + IREG_AH) : ((reg) + IREG_AL)) +#define IREG_16(reg) ((reg) + IREG_AX) +#define IREG_32(reg) ((reg) + IREG_EAX) -#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) -#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) -#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) -#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) +#define IREG_ST(r) (IREG_ST0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_D) +#define IREG_ST_i64(r) (IREG_ST0_i64 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_Q) +#define IREG_tag(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7)) +#define IREG_tag_B(r) (IREG_tag0 + ((cpu_state.TOP + (r)) & 7) + IREG_SIZE_B) -#define IREG_MM(reg) ((reg) + IREG_MM0) +#define IREG_MM(reg) ((reg) + IREG_MM0) #define IREG_TOP_diff_stack_offset 32 -static inline int ireg_seg_base(x86seg *seg) +static inline int +ireg_seg_base(x86seg *seg) { - if (seg == &cpu_state.seg_cs) - return IREG_CS_base; - if (seg == &cpu_state.seg_ds) - return IREG_DS_base; - if (seg == &cpu_state.seg_es) - return IREG_ES_base; - if (seg == &cpu_state.seg_fs) - return IREG_FS_base; - if (seg == &cpu_state.seg_gs) - return IREG_GS_base; - if (seg == &cpu_state.seg_ss) - return IREG_SS_base; - fatal("ireg_seg_base : unknown segment\n"); - return 0; + if (seg == &cpu_state.seg_cs) + return IREG_CS_base; + if (seg == &cpu_state.seg_ds) + return IREG_DS_base; + if (seg == &cpu_state.seg_es) + return IREG_ES_base; + if (seg == &cpu_state.seg_fs) + return IREG_FS_base; + if (seg == &cpu_state.seg_gs) + return IREG_GS_base; + if (seg == &cpu_state.seg_ss) + return IREG_SS_base; + fatal("ireg_seg_base : unknown segment\n"); + return 0; } -static inline int ireg_seg_limit_low(x86seg *seg) +static inline int +ireg_seg_limit_low(x86seg *seg) { - if (seg == &cpu_state.seg_cs) - return IREG_CS_limit_low; - if (seg == &cpu_state.seg_ds) - return IREG_DS_limit_low; - if (seg == &cpu_state.seg_es) - return IREG_ES_limit_low; - if (seg == &cpu_state.seg_fs) - return IREG_FS_limit_low; - if (seg == &cpu_state.seg_gs) - return IREG_GS_limit_low; - if (seg == &cpu_state.seg_ss) - return IREG_SS_limit_low; - fatal("ireg_seg_limit_low : unknown segment\n"); - return 0; + if (seg == &cpu_state.seg_cs) + return IREG_CS_limit_low; + if (seg == &cpu_state.seg_ds) + return IREG_DS_limit_low; + if (seg == &cpu_state.seg_es) + return IREG_ES_limit_low; + if (seg == &cpu_state.seg_fs) + return IREG_FS_limit_low; + if (seg == &cpu_state.seg_gs) + return IREG_GS_limit_low; + if (seg == &cpu_state.seg_ss) + return IREG_SS_limit_low; + fatal("ireg_seg_limit_low : unknown segment\n"); + return 0; } -static inline int ireg_seg_limit_high(x86seg *seg) +static inline int +ireg_seg_limit_high(x86seg *seg) { - if (seg == &cpu_state.seg_cs) - return IREG_CS_limit_high; - if (seg == &cpu_state.seg_ds) - return IREG_DS_limit_high; - if (seg == &cpu_state.seg_es) - return IREG_ES_limit_high; - if (seg == &cpu_state.seg_fs) - return IREG_FS_limit_high; - if (seg == &cpu_state.seg_gs) - return IREG_GS_limit_high; - if (seg == &cpu_state.seg_ss) - return IREG_SS_limit_high; - fatal("ireg_seg_limit_high : unknown segment\n"); - return 0; + if (seg == &cpu_state.seg_cs) + return IREG_CS_limit_high; + if (seg == &cpu_state.seg_ds) + return IREG_DS_limit_high; + if (seg == &cpu_state.seg_es) + return IREG_ES_limit_high; + if (seg == &cpu_state.seg_fs) + return IREG_FS_limit_high; + if (seg == &cpu_state.seg_gs) + return IREG_GS_limit_high; + if (seg == &cpu_state.seg_ss) + return IREG_SS_limit_high; + fatal("ireg_seg_limit_high : unknown segment\n"); + return 0; } extern uint8_t reg_last_version[IREG_COUNT]; @@ -279,18 +281,18 @@ extern uint8_t reg_last_version[IREG_COUNT]; apparently required or not. Do not optimise out.*/ #define REG_FLAGS_REQUIRED (1 << 0) /*This register and the parent uOP have been optimised out.*/ -#define REG_FLAGS_DEAD (1 << 1) +#define REG_FLAGS_DEAD (1 << 1) typedef struct { - /*Refcount of pending reads on this register version*/ - uint8_t refcount; - /*Flags*/ - uint8_t flags; - /*uOP that generated this register version*/ - uint16_t parent_uop; - /*Pointer to next register version in dead register list*/ - uint16_t next; + /*Refcount of pending reads on this register version*/ + uint8_t refcount; + /*Flags*/ + uint8_t flags; + /*uOP that generated this register version*/ + uint16_t parent_uop; + /*Pointer to next register version in dead register list*/ + uint16_t next; } reg_version_t; extern reg_version_t reg_version[IREG_COUNT][256]; @@ -299,16 +301,17 @@ extern reg_version_t reg_version[IREG_COUNT][256]; can be optimised out*/ extern uint16_t reg_dead_list; -static inline void add_to_dead_list(reg_version_t *regv, int reg, int version) +static inline void +add_to_dead_list(reg_version_t *regv, int reg, int version) { - regv->next = reg_dead_list; - reg_dead_list = version | (reg << 8); + regv->next = reg_dead_list; + reg_dead_list = version | (reg << 8); } typedef struct { - uint16_t reg; - uint16_t version; + uint16_t reg; + uint16_t version; } ir_reg_t; extern ir_reg_t invalid_ir_reg; @@ -317,80 +320,81 @@ typedef uint16_t ir_host_reg_t; extern int max_version_refcount; -#define REG_VERSION_MAX 250 +#define REG_VERSION_MAX 250 #define REG_REFCOUNT_MAX 250 -static inline ir_reg_t codegen_reg_read(int reg) +static inline ir_reg_t +codegen_reg_read(int reg) { - ir_reg_t ireg; - reg_version_t *version; + ir_reg_t ireg; + reg_version_t *version; #ifndef RELEASE_BUILD - if (IREG_GET_REG(reg) == IREG_INVALID) - fatal("codegen_reg_read - IREG_INVALID\n"); + if (IREG_GET_REG(reg) == IREG_INVALID) + fatal("codegen_reg_read - IREG_INVALID\n"); #endif - ireg.reg = reg; - ireg.version = reg_last_version[IREG_GET_REG(reg)]; - version = ®_version[IREG_GET_REG(ireg.reg)][ireg.version]; - version->flags = 0; - version->refcount++; + ireg.reg = reg; + ireg.version = reg_last_version[IREG_GET_REG(reg)]; + version = ®_version[IREG_GET_REG(ireg.reg)][ireg.version]; + version->flags = 0; + version->refcount++; #ifndef RELEASE_BUILD - if (!version->refcount) - fatal("codegen_reg_read - refcount overflow\n"); - else + if (!version->refcount) + fatal("codegen_reg_read - refcount overflow\n"); + else #endif if (version->refcount > REG_REFCOUNT_MAX) - CPU_BLOCK_END(); - if (version->refcount > max_version_refcount) - max_version_refcount = version->refcount; -// pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); - return ireg; + CPU_BLOCK_END(); + if (version->refcount > max_version_refcount) + max_version_refcount = version->refcount; + // pclog("codegen_reg_read: %i %i %i\n", reg & IREG_REG_MASK, ireg.version, reg_version_refcount[IREG_GET_REG(ireg.reg)][ireg.version]); + return ireg; } int reg_is_native_size(ir_reg_t ir_reg); -static inline ir_reg_t codegen_reg_write(int reg, int uop_nr) +static inline ir_reg_t +codegen_reg_write(int reg, int uop_nr) { - ir_reg_t ireg; - int last_version = reg_last_version[IREG_GET_REG(reg)]; - reg_version_t *version; + ir_reg_t ireg; + int last_version = reg_last_version[IREG_GET_REG(reg)]; + reg_version_t *version; #ifndef RELEASE_BUILD - if (IREG_GET_REG(reg) == IREG_INVALID) - fatal("codegen_reg_write - IREG_INVALID\n"); + if (IREG_GET_REG(reg) == IREG_INVALID) + fatal("codegen_reg_write - IREG_INVALID\n"); #endif - ireg.reg = reg; - ireg.version = last_version + 1; + ireg.reg = reg; + ireg.version = last_version + 1; - if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && - !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) - { - if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/ - add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); - } + if (IREG_GET_REG(reg) > IREG_EBX && last_version && !reg_version[IREG_GET_REG(reg)][last_version].refcount && !(reg_version[IREG_GET_REG(reg)][last_version].flags & REG_FLAGS_REQUIRED)) { + if (reg_is_native_size(ireg)) /*Non-native size registers have an implicit dependency on the previous version, so don't add to dead list*/ + add_to_dead_list(®_version[IREG_GET_REG(reg)][last_version], IREG_GET_REG(reg), last_version); + } - reg_last_version[IREG_GET_REG(reg)]++; + reg_last_version[IREG_GET_REG(reg)]++; #ifndef RELEASE_BUILD - if (!reg_last_version[IREG_GET_REG(reg)]) - fatal("codegen_reg_write - version overflow\n"); - else + if (!reg_last_version[IREG_GET_REG(reg)]) + fatal("codegen_reg_write - version overflow\n"); + else #endif if (reg_last_version[IREG_GET_REG(reg)] > REG_VERSION_MAX) - CPU_BLOCK_END(); - if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) - max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; + CPU_BLOCK_END(); + if (reg_last_version[IREG_GET_REG(reg)] > max_version_refcount) + max_version_refcount = reg_last_version[IREG_GET_REG(reg)]; - version = ®_version[IREG_GET_REG(reg)][ireg.version]; - version->refcount = 0; - version->flags = 0; - version->parent_uop = uop_nr; -// pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); - return ireg; + version = ®_version[IREG_GET_REG(reg)][ireg.version]; + version->refcount = 0; + version->flags = 0; + version->parent_uop = uop_nr; + // pclog("codegen_reg_write: %i\n", reg & IREG_REG_MASK); + return ireg; } -static inline int ir_reg_is_invalid(ir_reg_t ir_reg) +static inline int +ir_reg_is_invalid(ir_reg_t ir_reg) { - return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); + return (IREG_GET_REG(ir_reg.reg) == IREG_INVALID); } struct ir_data_t; @@ -405,7 +409,7 @@ void codegen_reg_flush_invalidate(struct ir_data_t *ir, codeblock_t *block); void codegen_reg_alloc_register(ir_reg_t dest_reg_a, ir_reg_t src_reg_a, ir_reg_t src_reg_b, ir_reg_t src_reg_c); #ifdef CODEGEN_BACKEND_HAS_MOV_IMM -int codegen_reg_is_loaded(ir_reg_t ir_reg); +int codegen_reg_is_loaded(ir_reg_t ir_reg); void codegen_reg_write_imm(codeblock_t *block, ir_reg_t ir_reg, uint32_t imm_data); #endif From 83b220cb0358739ae2ccd42ac479c5cd9d565f0c Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 19 Nov 2022 10:40:32 -0500 Subject: [PATCH 3/6] clang format in cpu --- src/cpu/386.c | 2 +- src/cpu/386_common.c | 1697 +++++++------- src/cpu/386_common.h | 568 +++-- src/cpu/386_dynarec.c | 1265 ++++++----- src/cpu/386_dynarec_ops.c | 70 +- src/cpu/386_ops.h | 446 ++-- src/cpu/8080.c | 199 +- src/cpu/808x.c | 84 +- src/cpu/codegen_public.h | 24 +- src/cpu/codegen_timing_common.h | 227 +- src/cpu/cpu.c | 2 +- src/cpu/cpu.h | 4 +- src/cpu/fpu.c | 24 +- src/cpu/x86.c | 249 +-- src/cpu/x86.h | 113 +- src/cpu/x86_flags.h | 1166 +++++----- src/cpu/x86_ops.h | 20 +- src/cpu/x86_ops_3dnow.h | 715 +++--- src/cpu/x86_ops_amd.h | 17 +- src/cpu/x86_ops_arith.h | 1625 ++++++++------ src/cpu/x86_ops_atomic.h | 448 ++-- src/cpu/x86_ops_bcd.h | 205 +- src/cpu/x86_ops_bit.h | 657 +++--- src/cpu/x86_ops_bitscan.h | 284 +-- src/cpu/x86_ops_call.h | 1358 +++++++----- src/cpu/x86_ops_cyrix.h | 407 ++-- src/cpu/x86_ops_flag.h | 576 ++--- src/cpu/x86_ops_fpu.h | 96 +- src/cpu/x86_ops_i686.h | 254 ++- src/cpu/x86_ops_inc_dec.h | 103 +- src/cpu/x86_ops_int.h | 144 +- src/cpu/x86_ops_io.h | 276 +-- src/cpu/x86_ops_jump.h | 652 +++--- src/cpu/x86_ops_misc.h | 1929 ++++++++-------- src/cpu/x86_ops_mmx.h | 76 +- src/cpu/x86_ops_mmx_arith.h | 1107 +++++----- src/cpu/x86_ops_mmx_cmp.h | 268 +-- src/cpu/x86_ops_mmx_logic.h | 120 +- src/cpu/x86_ops_mmx_mov.h | 344 +-- src/cpu/x86_ops_mmx_pack.h | 472 ++-- src/cpu/x86_ops_mmx_shift.h | 737 +++---- src/cpu/x86_ops_mov.h | 1471 +++++++------ src/cpu/x86_ops_mov_ctrl.h | 692 +++--- src/cpu/x86_ops_mov_seg.h | 879 ++++---- src/cpu/x86_ops_movx.h | 346 +-- src/cpu/x86_ops_msr.h | 49 +- src/cpu/x86_ops_mul.h | 454 ++-- src/cpu/x86_ops_pmode.h | 861 ++++---- src/cpu/x86_ops_prefix.h | 249 ++- src/cpu/x86_ops_rep.h | 1621 +++++++------- src/cpu/x86_ops_rep_dyn.h | 1461 +++++++------ src/cpu/x86_ops_ret.h | 528 +++-- src/cpu/x86_ops_set.h | 40 +- src/cpu/x86_ops_shift.h | 1742 ++++++++------- src/cpu/x86_ops_stack.h | 887 ++++---- src/cpu/x86_ops_string.h | 1569 +++++++------ src/cpu/x86_ops_xchg.h | 390 ++-- src/cpu/x86seg.c | 3639 ++++++++++++++++--------------- src/cpu/x87.c | 134 +- src/cpu/x87.h | 49 +- src/cpu/x87_ops.h | 648 +++--- src/cpu/x87_ops_arith.h | 795 +++---- src/cpu/x87_ops_conv.h | 91 +- src/cpu/x87_ops_loadstore.h | 832 +++---- src/cpu/x87_ops_misc.h | 1867 ++++++++-------- src/cpu/x87_timings.c | 147 +- 66 files changed, 21467 insertions(+), 19004 deletions(-) diff --git a/src/cpu/386.c b/src/cpu/386.c index 421a978bd..a5bae7de6 100644 --- a/src/cpu/386.c +++ b/src/cpu/386.c @@ -209,7 +209,7 @@ exec386(int cycs) enter_smm_check(0); else if (nmi && nmi_enable && nmi_mask) { #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; x86_int(2); diff --git a/src/cpu/386_common.c b/src/cpu/386_common.c index 24875ee4e..f8e7c11ce 100644 --- a/src/cpu/386_common.c +++ b/src/cpu/386_common.c @@ -6,7 +6,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H #include <86box/86box.h> @@ -28,20 +28,19 @@ #include "x86seg.h" #ifdef USE_DYNAREC -#include "codegen.h" -#define CPU_BLOCK_END() cpu_block_end = 1 +# include "codegen.h" +# define CPU_BLOCK_END() cpu_block_end = 1 #else -#define CPU_BLOCK_END() +# define CPU_BLOCK_END() #endif - x86seg gdt, ldt, idt, tr; uint32_t cr2, cr3, cr4; uint32_t dr[8]; uint32_t use32; -int stack32; +int stack32; uint32_t *eal_r, *eal_w; @@ -57,11 +56,10 @@ uint32_t cpu_cur_status = 0; extern uint8_t *pccache2; -extern int optype; +extern int optype; extern uint32_t pccache; - -int in_sys = 0, unmask_a20_in_smm = 0; +int in_sys = 0, unmask_a20_in_smm = 0; uint32_t old_rammask = 0xffffffff; int soft_reset_mask = 0; @@ -72,348 +70,339 @@ int smm_in_hlt = 0, smi_block = 0; uint32_t addr64, addr64_2; uint32_t addr64a[8], addr64a_2[8]; -static pc_timer_t *cpu_fast_off_timer = NULL; -static double cpu_fast_off_period = 0.0; - - -#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) -#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) -#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) +static pc_timer_t *cpu_fast_off_timer = NULL; +static double cpu_fast_off_period = 0.0; +#define AMD_SYSCALL_EIP (msr.star & 0xFFFFFFFF) +#define AMD_SYSCALL_SB ((msr.star >> 32) & 0xFFFF) +#define AMD_SYSRET_SB ((msr.star >> 48) & 0xFFFF) /* These #define's and enum have been borrowed from Bochs. */ /* SMM feature masks */ -#define SMM_IO_INSTRUCTION_RESTART (0x00010000) -#define SMM_SMBASE_RELOCATION (0x00020000) -#define SMM_REVISION (0x20000000) +#define SMM_IO_INSTRUCTION_RESTART (0x00010000) +#define SMM_SMBASE_RELOCATION (0x00020000) +#define SMM_REVISION (0x20000000) /* TODO: Which CPU added SMBASE relocation? */ -#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) +#define SMM_REVISION_ID (SMM_SMBASE_RELOCATION | SMM_IO_INSTRUCTION_RESTART | SMM_REVISION) #define SMM_SAVE_STATE_MAP_SIZE 128 - enum SMMRAM_Fields_386_To_P5 { - SMRAM_FIELD_P5_CR0 = 0, /* 1FC */ - SMRAM_FIELD_P5_CR3, /* 1F8 */ - SMRAM_FIELD_P5_EFLAGS, /* 1F4 */ - SMRAM_FIELD_P5_EIP, /* 1F0 */ - SMRAM_FIELD_P5_EDI, /* 1EC */ - SMRAM_FIELD_P5_ESI, /* 1E8 */ - SMRAM_FIELD_P5_EBP, /* 1E4 */ - SMRAM_FIELD_P5_ESP, /* 1E0 */ - SMRAM_FIELD_P5_EBX, /* 1DC */ - SMRAM_FIELD_P5_EDX, /* 1D8 */ - SMRAM_FIELD_P5_ECX, /* 1D4 */ - SMRAM_FIELD_P5_EAX, /* 1D0 */ - SMRAM_FIELD_P5_DR6, /* 1CC */ - SMRAM_FIELD_P5_DR7, /* 1C8 */ - SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */ - SMRAM_FIELD_P5_TR_BASE, /* 1A0 */ - SMRAM_FIELD_P5_TR_LIMIT, /* 19C */ - SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */ - SMRAM_FIELD_P5_IDTR_BASE, /* 194 */ - SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */ - SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */ - SMRAM_FIELD_P5_GDTR_BASE, /* 188 */ - SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */ - SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */ - SMRAM_FIELD_P5_LDTR_BASE, /* 17C */ - SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */ - SMRAM_FIELD_P5_GS_ACCESS, /* 174 */ - SMRAM_FIELD_P5_GS_BASE, /* 170 */ - SMRAM_FIELD_P5_GS_LIMIT, /* 16C */ - SMRAM_FIELD_P5_FS_ACCESS, /* 168 */ - SMRAM_FIELD_P5_FS_BASE, /* 164 */ - SMRAM_FIELD_P5_FS_LIMIT, /* 160 */ - SMRAM_FIELD_P5_DS_ACCESS, /* 15C */ - SMRAM_FIELD_P5_DS_BASE, /* 158 */ - SMRAM_FIELD_P5_DS_LIMIT, /* 154 */ - SMRAM_FIELD_P5_SS_ACCESS, /* 150 */ - SMRAM_FIELD_P5_SS_BASE, /* 14C */ - SMRAM_FIELD_P5_SS_LIMIT, /* 148 */ - SMRAM_FIELD_P5_CS_ACCESS, /* 144 */ - SMRAM_FIELD_P5_CS_BASE, /* 140 */ - SMRAM_FIELD_P5_CS_LIMIT, /* 13C */ - SMRAM_FIELD_P5_ES_ACCESS, /* 138 */ - SMRAM_FIELD_P5_ES_BASE, /* 134 */ - SMRAM_FIELD_P5_ES_LIMIT, /* 130 */ - SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */ - SMRAM_FIELD_P5_CR4, /* 128 */ - SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */ - SMRAM_FIELD_P5_RESERVED_1, /* 120 */ - SMRAM_FIELD_P5_RESERVED_2, /* 11C */ - SMRAM_FIELD_P5_RESERVED_3, /* 118 */ - SMRAM_FIELD_P5_RESERVED_4, /* 114 */ - SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */ - SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ - SMRAM_FIELD_AM486_CR2, /* 0F4 */ - SMRAM_FIELD_AM486_DR0, /* 0F0 */ - SMRAM_FIELD_AM486_DR1, /* 0EC */ - SMRAM_FIELD_AM486_DR2, /* 0E8 */ - SMRAM_FIELD_AM486_DR3, /* 0E4 */ + SMRAM_FIELD_P5_CR0 = 0, /* 1FC */ + SMRAM_FIELD_P5_CR3, /* 1F8 */ + SMRAM_FIELD_P5_EFLAGS, /* 1F4 */ + SMRAM_FIELD_P5_EIP, /* 1F0 */ + SMRAM_FIELD_P5_EDI, /* 1EC */ + SMRAM_FIELD_P5_ESI, /* 1E8 */ + SMRAM_FIELD_P5_EBP, /* 1E4 */ + SMRAM_FIELD_P5_ESP, /* 1E0 */ + SMRAM_FIELD_P5_EBX, /* 1DC */ + SMRAM_FIELD_P5_EDX, /* 1D8 */ + SMRAM_FIELD_P5_ECX, /* 1D4 */ + SMRAM_FIELD_P5_EAX, /* 1D0 */ + SMRAM_FIELD_P5_DR6, /* 1CC */ + SMRAM_FIELD_P5_DR7, /* 1C8 */ + SMRAM_FIELD_P5_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_P5_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_P5_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_P5_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_P5_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_P5_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_P5_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_P5_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_P5_TR_ACCESS, /* 1A4 */ + SMRAM_FIELD_P5_TR_BASE, /* 1A0 */ + SMRAM_FIELD_P5_TR_LIMIT, /* 19C */ + SMRAM_FIELD_P5_IDTR_ACCESS, /* 198 */ + SMRAM_FIELD_P5_IDTR_BASE, /* 194 */ + SMRAM_FIELD_P5_IDTR_LIMIT, /* 190 */ + SMRAM_FIELD_P5_GDTR_ACCESS, /* 18C */ + SMRAM_FIELD_P5_GDTR_BASE, /* 188 */ + SMRAM_FIELD_P5_GDTR_LIMIT, /* 184 */ + SMRAM_FIELD_P5_LDTR_ACCESS, /* 180 */ + SMRAM_FIELD_P5_LDTR_BASE, /* 17C */ + SMRAM_FIELD_P5_LDTR_LIMIT, /* 178 */ + SMRAM_FIELD_P5_GS_ACCESS, /* 174 */ + SMRAM_FIELD_P5_GS_BASE, /* 170 */ + SMRAM_FIELD_P5_GS_LIMIT, /* 16C */ + SMRAM_FIELD_P5_FS_ACCESS, /* 168 */ + SMRAM_FIELD_P5_FS_BASE, /* 164 */ + SMRAM_FIELD_P5_FS_LIMIT, /* 160 */ + SMRAM_FIELD_P5_DS_ACCESS, /* 15C */ + SMRAM_FIELD_P5_DS_BASE, /* 158 */ + SMRAM_FIELD_P5_DS_LIMIT, /* 154 */ + SMRAM_FIELD_P5_SS_ACCESS, /* 150 */ + SMRAM_FIELD_P5_SS_BASE, /* 14C */ + SMRAM_FIELD_P5_SS_LIMIT, /* 148 */ + SMRAM_FIELD_P5_CS_ACCESS, /* 144 */ + SMRAM_FIELD_P5_CS_BASE, /* 140 */ + SMRAM_FIELD_P5_CS_LIMIT, /* 13C */ + SMRAM_FIELD_P5_ES_ACCESS, /* 138 */ + SMRAM_FIELD_P5_ES_BASE, /* 134 */ + SMRAM_FIELD_P5_ES_LIMIT, /* 130 */ + SMRAM_FIELD_P5_UNWRITTEN_1, /* 12C */ + SMRAM_FIELD_P5_CR4, /* 128 */ + SMRAM_FIELD_P5_ALTERNATE_DR6, /* 124 */ + SMRAM_FIELD_P5_RESERVED_1, /* 120 */ + SMRAM_FIELD_P5_RESERVED_2, /* 11C */ + SMRAM_FIELD_P5_RESERVED_3, /* 118 */ + SMRAM_FIELD_P5_RESERVED_4, /* 114 */ + SMRAM_FIELD_P5_IO_RESTART_EIP, /* 110 */ + SMRAM_FIELD_P5_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_P5_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_P5_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_P5_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_P5_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_P5_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AM486_CR2, /* 0F4 */ + SMRAM_FIELD_AM486_DR0, /* 0F0 */ + SMRAM_FIELD_AM486_DR1, /* 0EC */ + SMRAM_FIELD_AM486_DR2, /* 0E8 */ + SMRAM_FIELD_AM486_DR3, /* 0E4 */ SMRAM_FIELD_P5_LAST }; enum SMMRAM_Fields_P6 { - SMRAM_FIELD_P6_CR0 = 0, /* 1FC */ - SMRAM_FIELD_P6_CR3, /* 1F8 */ - SMRAM_FIELD_P6_EFLAGS, /* 1F4 */ - SMRAM_FIELD_P6_EIP, /* 1F0 */ - SMRAM_FIELD_P6_EDI, /* 1EC */ - SMRAM_FIELD_P6_ESI, /* 1E8 */ - SMRAM_FIELD_P6_EBP, /* 1E4 */ - SMRAM_FIELD_P6_ESP, /* 1E0 */ - SMRAM_FIELD_P6_EBX, /* 1DC */ - SMRAM_FIELD_P6_EDX, /* 1D8 */ - SMRAM_FIELD_P6_ECX, /* 1D4 */ - SMRAM_FIELD_P6_EAX, /* 1D0 */ - SMRAM_FIELD_P6_DR6, /* 1CC */ - SMRAM_FIELD_P6_DR7, /* 1C8 */ - SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_P6_SS_BASE, /* 1A4 */ - SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */ - SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */ - SMRAM_FIELD_P6_CS_BASE, /* 198 */ - SMRAM_FIELD_P6_CS_LIMIT, /* 194 */ - SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */ - SMRAM_FIELD_P6_ES_BASE, /* 18C */ - SMRAM_FIELD_P6_ES_LIMIT, /* 188 */ - SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */ - SMRAM_FIELD_P6_LDTR_BASE, /* 180 */ - SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */ - SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */ - SMRAM_FIELD_P6_GDTR_BASE, /* 174 */ - SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */ - SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */ - SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */ - SMRAM_FIELD_P6_TR_BASE, /* 164 */ - SMRAM_FIELD_P6_TR_LIMIT, /* 160 */ - SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */ - SMRAM_FIELD_P6_IDTR_BASE, /* 158 */ - SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */ - SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */ - SMRAM_FIELD_P6_GS_BASE, /* 14C */ - SMRAM_FIELD_P6_GS_LIMIT, /* 148 */ - SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */ - SMRAM_FIELD_P6_FS_BASE, /* 140 */ - SMRAM_FIELD_P6_FS_LIMIT, /* 13C */ - SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */ - SMRAM_FIELD_P6_DS_BASE, /* 134 */ - SMRAM_FIELD_P6_DS_LIMIT, /* 130 */ - SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */ - SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */ - SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */ - SMRAM_FIELD_P6_CPL, /* 120 */ - SMRAM_FIELD_P6_SMM_STATUS, /* 11C */ - SMRAM_FIELD_P6_A20M, /* 118 */ - SMRAM_FIELD_P6_CR4, /* 114 */ - SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */ - SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_P6_CR0 = 0, /* 1FC */ + SMRAM_FIELD_P6_CR3, /* 1F8 */ + SMRAM_FIELD_P6_EFLAGS, /* 1F4 */ + SMRAM_FIELD_P6_EIP, /* 1F0 */ + SMRAM_FIELD_P6_EDI, /* 1EC */ + SMRAM_FIELD_P6_ESI, /* 1E8 */ + SMRAM_FIELD_P6_EBP, /* 1E4 */ + SMRAM_FIELD_P6_ESP, /* 1E0 */ + SMRAM_FIELD_P6_EBX, /* 1DC */ + SMRAM_FIELD_P6_EDX, /* 1D8 */ + SMRAM_FIELD_P6_ECX, /* 1D4 */ + SMRAM_FIELD_P6_EAX, /* 1D0 */ + SMRAM_FIELD_P6_DR6, /* 1CC */ + SMRAM_FIELD_P6_DR7, /* 1C8 */ + SMRAM_FIELD_P6_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_P6_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_P6_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_P6_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_P6_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_P6_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_P6_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_P6_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_P6_SS_BASE, /* 1A4 */ + SMRAM_FIELD_P6_SS_LIMIT, /* 1A0 */ + SMRAM_FIELD_P6_SS_SELECTOR_AR, /* 19C */ + SMRAM_FIELD_P6_CS_BASE, /* 198 */ + SMRAM_FIELD_P6_CS_LIMIT, /* 194 */ + SMRAM_FIELD_P6_CS_SELECTOR_AR, /* 190 */ + SMRAM_FIELD_P6_ES_BASE, /* 18C */ + SMRAM_FIELD_P6_ES_LIMIT, /* 188 */ + SMRAM_FIELD_P6_ES_SELECTOR_AR, /* 184 */ + SMRAM_FIELD_P6_LDTR_BASE, /* 180 */ + SMRAM_FIELD_P6_LDTR_LIMIT, /* 17C */ + SMRAM_FIELD_P6_LDTR_SELECTOR_AR, /* 178 */ + SMRAM_FIELD_P6_GDTR_BASE, /* 174 */ + SMRAM_FIELD_P6_GDTR_LIMIT, /* 170 */ + SMRAM_FIELD_P6_GDTR_SELECTOR_AR, /* 16C */ + SMRAM_FIELD_P6_SREG_STATUS1, /* 168 */ + SMRAM_FIELD_P6_TR_BASE, /* 164 */ + SMRAM_FIELD_P6_TR_LIMIT, /* 160 */ + SMRAM_FIELD_P6_TR_SELECTOR_AR, /* 15C */ + SMRAM_FIELD_P6_IDTR_BASE, /* 158 */ + SMRAM_FIELD_P6_IDTR_LIMIT, /* 154 */ + SMRAM_FIELD_P6_IDTR_SELECTOR_AR, /* 150 */ + SMRAM_FIELD_P6_GS_BASE, /* 14C */ + SMRAM_FIELD_P6_GS_LIMIT, /* 148 */ + SMRAM_FIELD_P6_GS_SELECTOR_AR, /* 144 */ + SMRAM_FIELD_P6_FS_BASE, /* 140 */ + SMRAM_FIELD_P6_FS_LIMIT, /* 13C */ + SMRAM_FIELD_P6_FS_SELECTOR_AR, /* 138 */ + SMRAM_FIELD_P6_DS_BASE, /* 134 */ + SMRAM_FIELD_P6_DS_LIMIT, /* 130 */ + SMRAM_FIELD_P6_DS_SELECTOR_AR, /* 12C */ + SMRAM_FIELD_P6_SREG_STATUS0, /* 128 */ + SMRAM_FIELD_P6_ALTERNATIVE_DR6, /* 124 */ + SMRAM_FIELD_P6_CPL, /* 120 */ + SMRAM_FIELD_P6_SMM_STATUS, /* 11C */ + SMRAM_FIELD_P6_A20M, /* 118 */ + SMRAM_FIELD_P6_CR4, /* 114 */ + SMRAM_FIELD_P6_IO_RESTART_EIP, /* 110 */ + SMRAM_FIELD_P6_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_P6_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_P6_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_P6_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_P6_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_P6_SMBASE_OFFSET, /* 0F8 */ SMRAM_FIELD_P6_LAST }; enum SMMRAM_Fields_AMD_K { - SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */ - SMRAM_FIELD_AMD_K_CR3, /* 1F8 */ - SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */ - SMRAM_FIELD_AMD_K_EIP, /* 1F0 */ - SMRAM_FIELD_AMD_K_EDI, /* 1EC */ - SMRAM_FIELD_AMD_K_ESI, /* 1E8 */ - SMRAM_FIELD_AMD_K_EBP, /* 1E4 */ - SMRAM_FIELD_AMD_K_ESP, /* 1E0 */ - SMRAM_FIELD_AMD_K_EBX, /* 1DC */ - SMRAM_FIELD_AMD_K_EDX, /* 1D8 */ - SMRAM_FIELD_AMD_K_ECX, /* 1D4 */ - SMRAM_FIELD_AMD_K_EAX, /* 1D0 */ - SMRAM_FIELD_AMD_K_DR6, /* 1CC */ - SMRAM_FIELD_AMD_K_DR7, /* 1C8 */ - SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */ - SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */ - SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */ - SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */ - SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */ - SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */ - SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */ - SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */ - SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */ - SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */ - SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */ - SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */ - SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */ - SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */ - SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */ - SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */ - SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */ - SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */ - SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */ - SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */ - SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */ - SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */ - SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */ - SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */ - SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */ - SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */ - SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */ - SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */ - SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */ - SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */ - SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */ - SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */ - SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */ - SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */ - SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */ - SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */ - SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */ - SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */ - SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */ - SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */ - SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */ - SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */ - SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */ - SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */ - SMRAM_FIELD_AMD_K_CR2, /* 114 */ - SMRAM_FIELD_AMD_K_CR4, /* 110 */ - SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */ - SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */ - SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */ - SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */ - SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */ - SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */ + SMRAM_FIELD_AMD_K_CR0 = 0, /* 1FC */ + SMRAM_FIELD_AMD_K_CR3, /* 1F8 */ + SMRAM_FIELD_AMD_K_EFLAGS, /* 1F4 */ + SMRAM_FIELD_AMD_K_EIP, /* 1F0 */ + SMRAM_FIELD_AMD_K_EDI, /* 1EC */ + SMRAM_FIELD_AMD_K_ESI, /* 1E8 */ + SMRAM_FIELD_AMD_K_EBP, /* 1E4 */ + SMRAM_FIELD_AMD_K_ESP, /* 1E0 */ + SMRAM_FIELD_AMD_K_EBX, /* 1DC */ + SMRAM_FIELD_AMD_K_EDX, /* 1D8 */ + SMRAM_FIELD_AMD_K_ECX, /* 1D4 */ + SMRAM_FIELD_AMD_K_EAX, /* 1D0 */ + SMRAM_FIELD_AMD_K_DR6, /* 1CC */ + SMRAM_FIELD_AMD_K_DR7, /* 1C8 */ + SMRAM_FIELD_AMD_K_TR_SELECTOR, /* 1C4 */ + SMRAM_FIELD_AMD_K_LDTR_SELECTOR, /* 1C0 */ + SMRAM_FIELD_AMD_K_GS_SELECTOR, /* 1BC */ + SMRAM_FIELD_AMD_K_FS_SELECTOR, /* 1B8 */ + SMRAM_FIELD_AMD_K_DS_SELECTOR, /* 1B4 */ + SMRAM_FIELD_AMD_K_SS_SELECTOR, /* 1B0 */ + SMRAM_FIELD_AMD_K_CS_SELECTOR, /* 1AC */ + SMRAM_FIELD_AMD_K_ES_SELECTOR, /* 1A8 */ + SMRAM_FIELD_AMD_K_IO_RESTART_DWORD, /* 1A4 */ + SMRAM_FIELD_AMD_K_RESERVED_1, /* 1A0 */ + SMRAM_FIELD_AMD_K_IO_RESTART_EIP, /* 19C */ + SMRAM_FIELD_AMD_K_RESERVED_2, /* 198 */ + SMRAM_FIELD_AMD_K_RESERVED_3, /* 194 */ + SMRAM_FIELD_AMD_K_IDTR_BASE, /* 190 */ + SMRAM_FIELD_AMD_K_IDTR_LIMIT, /* 18C */ + SMRAM_FIELD_AMD_K_GDTR_BASE, /* 188 */ + SMRAM_FIELD_AMD_K_GDTR_LIMIT, /* 184 */ + SMRAM_FIELD_AMD_K_TR_ACCESS, /* 180 */ + SMRAM_FIELD_AMD_K_TR_BASE, /* 17C */ + SMRAM_FIELD_AMD_K_TR_LIMIT, /* 178 */ + SMRAM_FIELD_AMD_K_LDTR_ACCESS, /* 174 - reserved on K6 */ + SMRAM_FIELD_AMD_K_LDTR_BASE, /* 170 */ + SMRAM_FIELD_AMD_K_LDTR_LIMIT, /* 16C */ + SMRAM_FIELD_AMD_K_GS_ACCESS, /* 168 */ + SMRAM_FIELD_AMD_K_GS_BASE, /* 164 */ + SMRAM_FIELD_AMD_K_GS_LIMIT, /* 160 */ + SMRAM_FIELD_AMD_K_FS_ACCESS, /* 15C */ + SMRAM_FIELD_AMD_K_FS_BASE, /* 158 */ + SMRAM_FIELD_AMD_K_FS_LIMIT, /* 154 */ + SMRAM_FIELD_AMD_K_DS_ACCESS, /* 150 */ + SMRAM_FIELD_AMD_K_DS_BASE, /* 14C */ + SMRAM_FIELD_AMD_K_DS_LIMIT, /* 148 */ + SMRAM_FIELD_AMD_K_SS_ACCESS, /* 144 */ + SMRAM_FIELD_AMD_K_SS_BASE, /* 140 */ + SMRAM_FIELD_AMD_K_SS_LIMIT, /* 13C */ + SMRAM_FIELD_AMD_K_CS_ACCESS, /* 138 */ + SMRAM_FIELD_AMD_K_CS_BASE, /* 134 */ + SMRAM_FIELD_AMD_K_CS_LIMIT, /* 130 */ + SMRAM_FIELD_AMD_K_ES_ACCESS, /* 12C */ + SMRAM_FIELD_AMD_K_ES_BASE, /* 128 */ + SMRAM_FIELD_AMD_K_ES_LIMIT, /* 124 */ + SMRAM_FIELD_AMD_K_RESERVED_4, /* 120 */ + SMRAM_FIELD_AMD_K_RESERVED_5, /* 11C */ + SMRAM_FIELD_AMD_K_RESERVED_6, /* 118 */ + SMRAM_FIELD_AMD_K_CR2, /* 114 */ + SMRAM_FIELD_AMD_K_CR4, /* 110 */ + SMRAM_FIELD_AMD_K_IO_RESTART_ESI, /* 10C */ + SMRAM_FIELD_AMD_K_IO_RESTART_ECX, /* 108 */ + SMRAM_FIELD_AMD_K_IO_RESTART_EDI, /* 104 */ + SMRAM_FIELD_AMD_K_AUTOHALT_RESTART, /* 100 */ + SMRAM_FIELD_AMD_K_SMM_REVISION_ID, /* 0FC */ + SMRAM_FIELD_AMD_K_SMBASE_OFFSET, /* 0F8 */ SMRAM_FIELD_AMD_K_LAST }; - #ifdef ENABLE_386_COMMON_LOG int x386_common_do_log = ENABLE_386_COMMON_LOG; - void x386_common_log(const char *fmt, ...) { va_list ap; if (x386_common_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x386_common_log(fmt, ...) +# define x386_common_log(fmt, ...) #endif - static __inline void set_stack32(int s) { - if ((cr0 & 1) && ! (cpu_state.eflags & VM_FLAG)) - stack32 = s; + if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) + stack32 = s; else - stack32 = 0; + stack32 = 0; if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; + cpu_cur_status |= CPU_STATUS_STACK32; else - cpu_cur_status &= ~CPU_STATUS_STACK32; + cpu_cur_status &= ~CPU_STATUS_STACK32; } - static __inline void set_use32(int u) { - if ((cr0 & 1) && ! (cpu_state.eflags & VM_FLAG)) - use32 = u ? 0x300 : 0; + if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) + use32 = u ? 0x300 : 0; else - use32 = 0; + use32 = 0; if (use32) - cpu_cur_status |= CPU_STATUS_USE32; + cpu_cur_status |= CPU_STATUS_USE32; else - cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_cur_status &= ~CPU_STATUS_USE32; } - static void smm_seg_load(x86seg *s) { if (!is386) - s->base &= 0x00ffffff; + s->base &= 0x00ffffff; if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) { - /* Expand down. */ - s->limit_high = s->limit; - s->limit_low = 0; + /* Expand down. */ + s->limit_high = s->limit; + s->limit_low = 0; } else { - s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; + s->limit_high = (s->ar_high & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; } if ((cr0 & 1) && !(cpu_state.eflags & VM_FLAG)) - s->checked = s->seg ? 1 : 0; + s->checked = s->seg ? 1 : 0; else - s->checked = 1; + s->checked = 1; if (s == &cpu_state.seg_cs) - set_use32(s->ar_high & 0x40); + set_use32(s->ar_high & 0x40); if (s == &cpu_state.seg_ds) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((s->ar_high & 0x40) ? 1 : 0); + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((s->ar_high & 0x40) ? 1 : 0); } } - static void smram_save_state_p5(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_P5_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_P5_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_P5_EIP] = cpu_state.pc; @@ -427,376 +416,367 @@ smram_save_state_p5(uint32_t *saved_state, int in_hlt) /* TR */ saved_state[SMRAM_FIELD_P5_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit; - saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); + saved_state[SMRAM_FIELD_P5_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_P5_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_P5_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); /* LDTR */ saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit; - saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); + saved_state[SMRAM_FIELD_P5_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_P5_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); /* IDTR */ - saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base; - saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit; + saved_state[SMRAM_FIELD_P5_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_P5_IDTR_LIMIT] = idt.limit; saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] = (idt.ar_high << 16) | (idt.access << 8); /* GDTR */ - saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base; - saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit; + saved_state[SMRAM_FIELD_P5_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_P5_GDTR_LIMIT] = gdt.limit; saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] = (gdt.ar_high << 16) | (gdt.access << 8); /* ES */ saved_state[SMRAM_FIELD_P5_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); + saved_state[SMRAM_FIELD_P5_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_P5_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_P5_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); /* CS */ saved_state[SMRAM_FIELD_P5_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); + saved_state[SMRAM_FIELD_P5_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_P5_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_P5_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); /* DS */ saved_state[SMRAM_FIELD_P5_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); + saved_state[SMRAM_FIELD_P5_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_P5_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_P5_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); /* SS */ saved_state[SMRAM_FIELD_P5_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); + saved_state[SMRAM_FIELD_P5_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_P5_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_P5_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); /* FS */ saved_state[SMRAM_FIELD_P5_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); + saved_state[SMRAM_FIELD_P5_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_P5_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_P5_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); /* GS */ saved_state[SMRAM_FIELD_P5_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + saved_state[SMRAM_FIELD_P5_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_P5_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_P5_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); /* Am486/5x86 stuff */ if (!is_pentium) { - saved_state[SMRAM_FIELD_AM486_CR2] = cr2; - saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; - saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; - saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; - saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; + saved_state[SMRAM_FIELD_AM486_CR2] = cr2; + saved_state[SMRAM_FIELD_AM486_DR0] = dr[0]; + saved_state[SMRAM_FIELD_AM486_DR1] = dr[1]; + saved_state[SMRAM_FIELD_AM486_DR2] = dr[2]; + saved_state[SMRAM_FIELD_AM486_DR3] = dr[3]; } } - static void smram_restore_state_p5(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P5_EAX - n]; if (saved_state[SMRAM_FIELD_P5_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_P5_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_P5_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_P5_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_P5_CR0]; - cr3 = saved_state[SMRAM_FIELD_P5_CR3]; - cr4 = saved_state[SMRAM_FIELD_P5_CR4]; + cr0 = saved_state[SMRAM_FIELD_P5_CR0]; + cr3 = saved_state[SMRAM_FIELD_P5_CR3]; + cr4 = saved_state[SMRAM_FIELD_P5_CR4]; dr[6] = saved_state[SMRAM_FIELD_P5_DR6]; dr[7] = saved_state[SMRAM_FIELD_P5_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_P5_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_P5_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_P5_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 8) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_P5_TR_ACCESS] >> 16) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE]; - ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT]; - ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff; + ldt.seg = saved_state[SMRAM_FIELD_P5_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_P5_LDTR_BASE]; + ldt.limit = saved_state[SMRAM_FIELD_P5_LDTR_LIMIT]; + ldt.access = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 8) & 0xff; ldt.ar_high = (saved_state[SMRAM_FIELD_P5_LDTR_ACCESS] >> 16) & 0xff; smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE]; - idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT]; - idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff; + idt.base = saved_state[SMRAM_FIELD_P5_IDTR_BASE]; + idt.limit = saved_state[SMRAM_FIELD_P5_IDTR_LIMIT]; + idt.access = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 8) & 0xff; idt.ar_high = (saved_state[SMRAM_FIELD_P5_IDTR_ACCESS] >> 16) & 0xff; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE]; - gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT]; - gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff; + gdt.base = saved_state[SMRAM_FIELD_P5_GDTR_BASE]; + gdt.limit = saved_state[SMRAM_FIELD_P5_GDTR_LIMIT]; + gdt.access = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 8) & 0xff; gdt.ar_high = (saved_state[SMRAM_FIELD_P5_GDTR_ACCESS] >> 16) & 0xff; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P5_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P5_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P5_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 8) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P5_ES_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P5_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P5_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P5_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 8) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P5_CS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_cs); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P5_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P5_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P5_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 8) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P5_DS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT]; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P5_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P5_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P5_SS_LIMIT]; cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 8) & 0xff; /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */ - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P5_SS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P5_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P5_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P5_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 8) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P5_FS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P5_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P5_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P5_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 8) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P5_GS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET]; /* Am486/5x86 stuff */ if (!is_pentium) { - cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; - dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; - dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; - dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; - dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; + cr2 = saved_state[SMRAM_FIELD_AM486_CR2]; + dr[0] = saved_state[SMRAM_FIELD_AM486_DR0]; + dr[1] = saved_state[SMRAM_FIELD_AM486_DR1]; + dr[2] = saved_state[SMRAM_FIELD_AM486_DR2]; + dr[3] = saved_state[SMRAM_FIELD_AM486_DR3]; } } - static void smram_save_state_p6(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_P6_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_P6_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_P6_EIP] = cpu_state.pc; saved_state[SMRAM_FIELD_P6_EFLAGS] = (cpu_state.eflags << 16) | (cpu_state.flags); - saved_state[SMRAM_FIELD_P6_CR0] = cr0; - saved_state[SMRAM_FIELD_P6_CR3] = cr3; - saved_state[SMRAM_FIELD_P6_CR4] = cr4; - saved_state[SMRAM_FIELD_P6_DR6] = dr[6]; - saved_state[SMRAM_FIELD_P6_DR7] = dr[7]; - saved_state[SMRAM_FIELD_P6_CPL] = CPL; + saved_state[SMRAM_FIELD_P6_CR0] = cr0; + saved_state[SMRAM_FIELD_P6_CR3] = cr3; + saved_state[SMRAM_FIELD_P6_CR4] = cr4; + saved_state[SMRAM_FIELD_P6_DR6] = dr[6]; + saved_state[SMRAM_FIELD_P6_DR7] = dr[7]; + saved_state[SMRAM_FIELD_P6_CPL] = CPL; saved_state[SMRAM_FIELD_P6_A20M] = !mem_a20_state; /* TR */ - saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_P6_TR_SELECTOR] = tr.seg; + saved_state[SMRAM_FIELD_P6_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_P6_TR_LIMIT] = tr.limit; saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] = (tr.ar_high << 24) | (tr.access << 16) | tr.seg; /* LDTR */ - saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR] = ldt.seg; + saved_state[SMRAM_FIELD_P6_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_P6_LDTR_LIMIT] = ldt.limit; saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] = (ldt.ar_high << 24) | (ldt.access << 16) | ldt.seg; /* IDTR */ - saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base; - saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit; + saved_state[SMRAM_FIELD_P6_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_P6_IDTR_LIMIT] = idt.limit; saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] = (idt.ar_high << 24) | (idt.access << 16) | idt.seg; /* GDTR */ - saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base; - saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit; + saved_state[SMRAM_FIELD_P6_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_P6_GDTR_LIMIT] = gdt.limit; saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] = (gdt.ar_high << 24) | (gdt.access << 16) | gdt.seg; /* ES */ - saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] = - (cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg; + saved_state[SMRAM_FIELD_P6_ES_SELECTOR] = cpu_state.seg_es.seg; + saved_state[SMRAM_FIELD_P6_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_P6_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] = (cpu_state.seg_es.ar_high << 24) | (cpu_state.seg_es.access << 16) | cpu_state.seg_es.seg; /* CS */ - saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] = - (cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg; + saved_state[SMRAM_FIELD_P6_CS_SELECTOR] = cpu_state.seg_cs.seg; + saved_state[SMRAM_FIELD_P6_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_P6_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] = (cpu_state.seg_cs.ar_high << 24) | (cpu_state.seg_cs.access << 16) | cpu_state.seg_cs.seg; /* DS */ - saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] = - (cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg; + saved_state[SMRAM_FIELD_P6_DS_SELECTOR] = cpu_state.seg_ds.seg; + saved_state[SMRAM_FIELD_P6_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_P6_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] = (cpu_state.seg_ds.ar_high << 24) | (cpu_state.seg_ds.access << 16) | cpu_state.seg_ds.seg; /* SS */ - saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] = - (cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg; + saved_state[SMRAM_FIELD_P6_SS_SELECTOR] = cpu_state.seg_ss.seg; + saved_state[SMRAM_FIELD_P6_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_P6_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] = (cpu_state.seg_ss.ar_high << 24) | (cpu_state.seg_ss.access << 16) | cpu_state.seg_ss.seg; /* FS */ - saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] = - (cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg; + saved_state[SMRAM_FIELD_P6_FS_SELECTOR] = cpu_state.seg_fs.seg; + saved_state[SMRAM_FIELD_P6_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_P6_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] = (cpu_state.seg_fs.ar_high << 24) | (cpu_state.seg_fs.access << 16) | cpu_state.seg_fs.seg; /* GS */ - saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] = - (cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg; + saved_state[SMRAM_FIELD_P6_GS_SELECTOR] = cpu_state.seg_gs.seg; + saved_state[SMRAM_FIELD_P6_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_P6_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] = (cpu_state.seg_gs.ar_high << 24) | (cpu_state.seg_gs.access << 16) | cpu_state.seg_gs.seg; } - static void smram_restore_state_p6(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_P6_EAX - n]; if (saved_state[SMRAM_FIELD_P6_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_P6_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_P6_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_P6_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_P6_CR0]; - cr3 = saved_state[SMRAM_FIELD_P6_CR3]; - cr4 = saved_state[SMRAM_FIELD_P6_CR4]; + cr0 = saved_state[SMRAM_FIELD_P6_CR0]; + cr3 = saved_state[SMRAM_FIELD_P6_CR3]; + cr4 = saved_state[SMRAM_FIELD_P6_CR4]; dr[6] = saved_state[SMRAM_FIELD_P6_DR6]; dr[7] = saved_state[SMRAM_FIELD_P6_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_P6_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_P6_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_P6_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 16) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_P6_TR_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE]; - ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT]; - ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff; + ldt.seg = saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_P6_LDTR_BASE]; + ldt.limit = saved_state[SMRAM_FIELD_P6_LDTR_LIMIT]; + ldt.access = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 16) & 0xff; ldt.ar_high = (saved_state[SMRAM_FIELD_P6_LDTR_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE]; - idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT]; - idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff; + idt.base = saved_state[SMRAM_FIELD_P6_IDTR_BASE]; + idt.limit = saved_state[SMRAM_FIELD_P6_IDTR_LIMIT]; + idt.access = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 16) & 0xff; idt.ar_high = (saved_state[SMRAM_FIELD_P6_IDTR_SELECTOR_AR] >> 24) & 0xff; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE]; - gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT]; - gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff; + gdt.base = saved_state[SMRAM_FIELD_P6_GDTR_BASE]; + gdt.limit = saved_state[SMRAM_FIELD_P6_GDTR_LIMIT]; + gdt.access = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 16) & 0xff; gdt.ar_high = (saved_state[SMRAM_FIELD_P6_GDTR_SELECTOR_AR] >> 24) & 0xff; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_P6_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_P6_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_P6_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_P6_ES_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_P6_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_P6_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_P6_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_P6_CS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_cs); cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((saved_state[SMRAM_FIELD_P6_CPL] & 0x03) << 5); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_P6_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_P6_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_P6_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_P6_DS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT]; - cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_P6_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_P6_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_P6_SS_LIMIT]; + cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_P6_SS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_P6_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_P6_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_P6_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_P6_FS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_P6_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_P6_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_P6_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 16) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_P6_GS_SELECTOR_AR] >> 24) & 0xff; smm_seg_load(&cpu_state.seg_gs); @@ -805,25 +785,24 @@ smram_restore_state_p6(uint32_t *saved_state) mem_a20_recalc(); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_P6_SMBASE_OFFSET]; } - static void smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) { int n = 0; saved_state[SMRAM_FIELD_AMD_K_SMM_REVISION_ID] = SMM_REVISION_ID; - saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; + saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET] = smbase; for (n = 0; n < 8; n++) - saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; + saved_state[SMRAM_FIELD_AMD_K_EAX - n] = cpu_state.regs[n].l; if (in_hlt) - saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1; + saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 1; else - saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0; + saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] = 0; saved_state[SMRAM_FIELD_AMD_K_EIP] = cpu_state.pc; @@ -838,167 +817,165 @@ smram_save_state_amd_k(uint32_t *saved_state, int in_hlt) /* TR */ saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR] = tr.seg; - saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base; - saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit; - saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); + saved_state[SMRAM_FIELD_AMD_K_TR_BASE] = tr.base; + saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT] = tr.limit; + saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] = (tr.ar_high << 16) | (tr.access << 8); /* LDTR */ saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR] = ldt.seg; - saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base; - saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit; + saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE] = ldt.base; + saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT] = ldt.limit; if (!is_k6) - saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); + saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] = (ldt.ar_high << 16) | (ldt.access << 8); /* IDTR */ - saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base; + saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE] = idt.base; saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT] = idt.limit; /* GDTR */ - saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base; + saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE] = gdt.base; saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT] = gdt.limit; /* ES */ saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR] = cpu_state.seg_es.seg; - saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base; - saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit; - saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); + saved_state[SMRAM_FIELD_AMD_K_ES_BASE] = cpu_state.seg_es.base; + saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT] = cpu_state.seg_es.limit; + saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] = (cpu_state.seg_es.ar_high << 16) | (cpu_state.seg_es.access << 8); /* CS */ saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR] = cpu_state.seg_cs.seg; - saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base; - saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit; - saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_CS_BASE] = cpu_state.seg_cs.base; + saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT] = cpu_state.seg_cs.limit; + saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] = (cpu_state.seg_cs.ar_high << 16) | (cpu_state.seg_cs.access << 8); /* DS */ saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR] = cpu_state.seg_ds.seg; - saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base; - saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit; - saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); + saved_state[SMRAM_FIELD_AMD_K_DS_BASE] = cpu_state.seg_ds.base; + saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT] = cpu_state.seg_ds.limit; + saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] = (cpu_state.seg_ds.ar_high << 16) | (cpu_state.seg_ds.access << 8); /* SS */ saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR] = cpu_state.seg_ss.seg; - saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base; - saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit; - saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); + saved_state[SMRAM_FIELD_AMD_K_SS_BASE] = cpu_state.seg_ss.base; + saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT] = cpu_state.seg_ss.limit; + saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] = (cpu_state.seg_ss.ar_high << 16) | (cpu_state.seg_ss.access << 8); /* FS */ saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR] = cpu_state.seg_fs.seg; - saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base; - saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit; - saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_FS_BASE] = cpu_state.seg_fs.base; + saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT] = cpu_state.seg_fs.limit; + saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] = (cpu_state.seg_fs.ar_high << 16) | (cpu_state.seg_fs.access << 8); /* GS */ saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR] = cpu_state.seg_gs.seg; - saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base; - saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit; - saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); + saved_state[SMRAM_FIELD_AMD_K_GS_BASE] = cpu_state.seg_gs.base; + saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT] = cpu_state.seg_gs.limit; + saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] = (cpu_state.seg_gs.ar_high << 16) | (cpu_state.seg_gs.access << 8); } - static void smram_restore_state_amd_k(uint32_t *saved_state) { int n = 0; for (n = 0; n < 8; n++) - cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; + cpu_state.regs[n].l = saved_state[SMRAM_FIELD_AMD_K_EAX - n]; if (saved_state[SMRAM_FIELD_AMD_K_AUTOHALT_RESTART] & 0xffff) - cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1; + cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP] - 1; else - cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP]; + cpu_state.pc = saved_state[SMRAM_FIELD_AMD_K_EIP]; cpu_state.eflags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] >> 16; - cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff; + cpu_state.flags = saved_state[SMRAM_FIELD_AMD_K_EFLAGS] & 0xffff; - cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0]; - cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2]; - cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3]; - cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4]; + cr0 = saved_state[SMRAM_FIELD_AMD_K_CR0]; + cr2 = saved_state[SMRAM_FIELD_AMD_K_CR2]; + cr3 = saved_state[SMRAM_FIELD_AMD_K_CR3]; + cr4 = saved_state[SMRAM_FIELD_AMD_K_CR4]; dr[6] = saved_state[SMRAM_FIELD_AMD_K_DR6]; dr[7] = saved_state[SMRAM_FIELD_AMD_K_DR7]; /* TR */ - tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR]; - tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE]; - tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT]; - tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff; + tr.seg = saved_state[SMRAM_FIELD_AMD_K_TR_SELECTOR]; + tr.base = saved_state[SMRAM_FIELD_AMD_K_TR_BASE]; + tr.limit = saved_state[SMRAM_FIELD_AMD_K_TR_LIMIT]; + tr.access = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 8) & 0xff; tr.ar_high = (saved_state[SMRAM_FIELD_AMD_K_TR_ACCESS] >> 16) & 0xff; smm_seg_load(&tr); /* LDTR */ - ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR]; - ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE]; + ldt.seg = saved_state[SMRAM_FIELD_AMD_K_LDTR_SELECTOR]; + ldt.base = saved_state[SMRAM_FIELD_AMD_K_LDTR_BASE]; ldt.limit = saved_state[SMRAM_FIELD_AMD_K_LDTR_LIMIT]; if (!is_k6) { - ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff; - ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff; + ldt.access = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 8) & 0xff; + ldt.ar_high = (saved_state[SMRAM_FIELD_AMD_K_LDTR_ACCESS] >> 16) & 0xff; } smm_seg_load(&ldt); /* IDTR */ - idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE]; + idt.base = saved_state[SMRAM_FIELD_AMD_K_IDTR_BASE]; idt.limit = saved_state[SMRAM_FIELD_AMD_K_IDTR_LIMIT]; /* GDTR */ - gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE]; + gdt.base = saved_state[SMRAM_FIELD_AMD_K_GDTR_BASE]; gdt.limit = saved_state[SMRAM_FIELD_AMD_K_GDTR_LIMIT]; /* ES */ - cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR]; - cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE]; - cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT]; - cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff; + cpu_state.seg_es.seg = saved_state[SMRAM_FIELD_AMD_K_ES_SELECTOR]; + cpu_state.seg_es.base = saved_state[SMRAM_FIELD_AMD_K_ES_BASE]; + cpu_state.seg_es.limit = saved_state[SMRAM_FIELD_AMD_K_ES_LIMIT]; + cpu_state.seg_es.access = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 8) & 0xff; cpu_state.seg_es.ar_high = (saved_state[SMRAM_FIELD_AMD_K_ES_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_es); /* CS */ - cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR]; - cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE]; - cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT]; - cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff; + cpu_state.seg_cs.seg = saved_state[SMRAM_FIELD_AMD_K_CS_SELECTOR]; + cpu_state.seg_cs.base = saved_state[SMRAM_FIELD_AMD_K_CS_BASE]; + cpu_state.seg_cs.limit = saved_state[SMRAM_FIELD_AMD_K_CS_LIMIT]; + cpu_state.seg_cs.access = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 8) & 0xff; cpu_state.seg_cs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_CS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_cs); /* DS */ - cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR]; - cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE]; - cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT]; - cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff; + cpu_state.seg_ds.seg = saved_state[SMRAM_FIELD_AMD_K_DS_SELECTOR]; + cpu_state.seg_ds.base = saved_state[SMRAM_FIELD_AMD_K_DS_BASE]; + cpu_state.seg_ds.limit = saved_state[SMRAM_FIELD_AMD_K_DS_LIMIT]; + cpu_state.seg_ds.access = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 8) & 0xff; cpu_state.seg_ds.ar_high = (saved_state[SMRAM_FIELD_AMD_K_DS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ds); /* SS */ - cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR]; - cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE]; - cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT]; + cpu_state.seg_ss.seg = saved_state[SMRAM_FIELD_AMD_K_SS_SELECTOR]; + cpu_state.seg_ss.base = saved_state[SMRAM_FIELD_AMD_K_SS_BASE]; + cpu_state.seg_ss.limit = saved_state[SMRAM_FIELD_AMD_K_SS_LIMIT]; cpu_state.seg_ss.access = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 8) & 0xff; /* The actual CPL (DPL of CS) is overwritten with DPL of SS. */ - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (cpu_state.seg_ss.access & 0x60); cpu_state.seg_ss.ar_high = (saved_state[SMRAM_FIELD_AMD_K_SS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_ss); /* FS */ - cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR]; - cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE]; - cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT]; - cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff; + cpu_state.seg_fs.seg = saved_state[SMRAM_FIELD_AMD_K_FS_SELECTOR]; + cpu_state.seg_fs.base = saved_state[SMRAM_FIELD_AMD_K_FS_BASE]; + cpu_state.seg_fs.limit = saved_state[SMRAM_FIELD_AMD_K_FS_LIMIT]; + cpu_state.seg_fs.access = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 8) & 0xff; cpu_state.seg_fs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_FS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_fs); /* GS */ - cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR]; - cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE]; - cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT]; - cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff; + cpu_state.seg_gs.seg = saved_state[SMRAM_FIELD_AMD_K_GS_SELECTOR]; + cpu_state.seg_gs.base = saved_state[SMRAM_FIELD_AMD_K_GS_BASE]; + cpu_state.seg_gs.limit = saved_state[SMRAM_FIELD_AMD_K_GS_LIMIT]; + cpu_state.seg_gs.access = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 8) & 0xff; cpu_state.seg_gs.ar_high = (saved_state[SMRAM_FIELD_AMD_K_GS_ACCESS] >> 16) & 0xff; smm_seg_load(&cpu_state.seg_gs); if (SMM_REVISION_ID & SMM_SMBASE_RELOCATION) - smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET]; + smbase = saved_state[SMRAM_FIELD_AMD_K_SMBASE_OFFSET]; } - static void smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) { @@ -1011,18 +988,16 @@ smram_save_state_cyrix(uint32_t *saved_state, int in_hlt) saved_state[6] = 0x00000000; } - static void smram_restore_state_cyrix(uint32_t *saved_state) { - dr[7] = saved_state[0]; - cpu_state.flags = saved_state[1] & 0xffff; + dr[7] = saved_state[0]; + cpu_state.flags = saved_state[1] & 0xffff; cpu_state.eflags = saved_state[1] >> 16; - cr0 = saved_state[2]; - cpu_state.pc = saved_state[4]; + cr0 = saved_state[2]; + cpu_state.pc = saved_state[4]; } - void enter_smm(int in_hlt) { @@ -1031,39 +1006,39 @@ enter_smm(int in_hlt) /* If it's a CPU on which SMM is not supported, do nothing. */ if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) - return; + return; x386_common_log("enter_smm(): smbase = %08X\n", smbase); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, - cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); + cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, + cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); x386_common_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, - cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); + cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, + cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); x386_common_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, - cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); + cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, + cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); x386_common_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); + cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); x386_common_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); + cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); x386_common_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, - cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); + cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, + cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); x386_common_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); + tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); x386_common_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); + ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); x386_common_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); + gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); x386_common_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); + idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); x386_common_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]); x386_common_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags); x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", - EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); + EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); flags_rebuild(); in_smm = 1; @@ -1071,24 +1046,24 @@ enter_smm(int in_hlt) smram_recalc_all(0); if (is_cxsmm) { - if (!(cyrix.smhr & SMHR_VALID)) - cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; - smram_state = cyrix.smhr & SMHR_ADDR_MASK; + if (!(cyrix.smhr & SMHR_VALID)) + cyrix.smhr = (cyrix.arr[3].base + cyrix.arr[3].size) | SMHR_VALID; + smram_state = cyrix.smhr & SMHR_ADDR_MASK; } memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); - if (is_cxsmm) /* Cx6x86 */ - smram_save_state_cyrix(saved_state, in_hlt); - else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ - smram_save_state_p5(saved_state, in_hlt); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ - smram_save_state_amd_k(saved_state, in_hlt); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ - smram_save_state_p6(saved_state, in_hlt); + if (is_cxsmm) /* Cx6x86 */ + smram_save_state_cyrix(saved_state, in_hlt); + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + smram_save_state_p5(saved_state, in_hlt); + else if (is_k5 || is_k6) /* AMD K5 and K6 */ + smram_save_state_amd_k(saved_state, in_hlt); + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + smram_save_state_p6(saved_state, in_hlt); cr0 &= ~0x8000000d; - cpu_state.flags = 2; + cpu_state.flags = 2; cpu_state.eflags = 0; cr4 = 0; @@ -1096,87 +1071,87 @@ enter_smm(int in_hlt) dr[7] = 0x400; if (is_cxsmm) { - cpu_state.pc = 0x0000; - cpl_override = 1; - cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); - cpl_override = 0; - cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); - cpu_state.seg_cs.base = cyrix.arr[3].base; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.access = 0x93; - cpu_state.seg_cs.ar_high = 0x80; - cpu_state.seg_cs.checked = 1; + cpu_state.pc = 0x0000; + cpl_override = 1; + cyrix_write_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + cpl_override = 0; + cpu_state.seg_cs.seg = (cyrix.arr[3].base >> 4); + cpu_state.seg_cs.base = cyrix.arr[3].base; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.ar_high = 0x80; + cpu_state.seg_cs.checked = 1; - smm_seg_load(&cpu_state.seg_cs); + smm_seg_load(&cpu_state.seg_cs); } else { - cpu_state.pc = 0x8000; - cpu_state.seg_ds.seg = 0x00000000; - cpu_state.seg_ds.base = 0x00000000; - cpu_state.seg_ds.limit = 0xffffffff; - cpu_state.seg_ds.access = 0x93; - cpu_state.seg_ds.ar_high = 0x80; + cpu_state.pc = 0x8000; + cpu_state.seg_ds.seg = 0x00000000; + cpu_state.seg_ds.base = 0x00000000; + cpu_state.seg_ds.limit = 0xffffffff; + cpu_state.seg_ds.access = 0x93; + cpu_state.seg_ds.ar_high = 0x80; - memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg)); - memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_es, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_ss, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_fs, &cpu_state.seg_ds, sizeof(x86seg)); + memcpy(&cpu_state.seg_gs, &cpu_state.seg_ds, sizeof(x86seg)); - if (is_p6) - cpu_state.seg_cs.seg = (smbase >> 4); - else - cpu_state.seg_cs.seg = 0x3000; + if (is_p6) + cpu_state.seg_cs.seg = (smbase >> 4); + else + cpu_state.seg_cs.seg = 0x3000; - /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */ - cpu_state.seg_cs.base = smbase; - cpu_state.seg_cs.limit = 0xffffffff; - cpu_state.seg_cs.access = 0x93; - cpu_state.seg_cs.ar_high = 0x80; - cpu_state.seg_cs.checked = 1; + /* On Pentium, CS selector in SMM is always 3000, regardless of SMBASE. */ + cpu_state.seg_cs.base = smbase; + cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.access = 0x93; + cpu_state.seg_cs.ar_high = 0x80; + cpu_state.seg_cs.checked = 1; - smm_seg_load(&cpu_state.seg_es); - smm_seg_load(&cpu_state.seg_cs); - smm_seg_load(&cpu_state.seg_ds); - smm_seg_load(&cpu_state.seg_ss); - smm_seg_load(&cpu_state.seg_fs); - smm_seg_load(&cpu_state.seg_gs); + smm_seg_load(&cpu_state.seg_es); + smm_seg_load(&cpu_state.seg_cs); + smm_seg_load(&cpu_state.seg_ds); + smm_seg_load(&cpu_state.seg_ss); + smm_seg_load(&cpu_state.seg_fs); + smm_seg_load(&cpu_state.seg_gs); } cpu_state.op32 = use32; cpl_override = 1; if (is_cxsmm) { - writememl(0, smram_state - 0x04, saved_state[0]); - writememl(0, smram_state - 0x08, saved_state[1]); - writememl(0, smram_state - 0x0c, saved_state[2]); - writememl(0, smram_state - 0x10, saved_state[3]); - writememl(0, smram_state - 0x14, saved_state[4]); - writememl(0, smram_state - 0x18, saved_state[5]); - writememl(0, smram_state - 0x24, saved_state[6]); + writememl(0, smram_state - 0x04, saved_state[0]); + writememl(0, smram_state - 0x08, saved_state[1]); + writememl(0, smram_state - 0x0c, saved_state[2]); + writememl(0, smram_state - 0x10, saved_state[3]); + writememl(0, smram_state - 0x14, saved_state[4]); + writememl(0, smram_state - 0x18, saved_state[5]); + writememl(0, smram_state - 0x24, saved_state[6]); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { - smram_state -= 4; - writememl(0, smram_state, saved_state[n]); - } + for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + smram_state -= 4; + writememl(0, smram_state, saved_state[n]); + } } cpl_override = 0; nmi_mask = 0; if (smi_latched) { - in_smm = 2; - smi_latched = 0; + in_smm = 2; + smi_latched = 0; } else - in_smm = 1; + in_smm = 1; smm_in_hlt = in_hlt; if (unmask_a20_in_smm) { - old_rammask = rammask; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x3000000; + old_rammask = rammask; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x3000000; - flushmmucache(); + flushmmucache(); } oldcpl = 0; @@ -1185,33 +1160,31 @@ enter_smm(int in_hlt) CPU_BLOCK_END(); } - void enter_smm_check(int in_hlt) { if ((in_smm == 0) && smi_line) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while not in SMM\n"); + x386_common_log("SMI while not in SMM\n"); #endif - enter_smm(in_hlt); + enter_smm(in_hlt); } else if ((in_smm == 1) && smi_line) { - /* Mark this so that we don't latch more than one SMI. */ + /* Mark this so that we don't latch more than one SMI. */ #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while in unlatched SMM\n"); + x386_common_log("SMI while in unlatched SMM\n"); #endif - smi_latched = 1; + smi_latched = 1; } else if ((in_smm == 2) && smi_line) { - /* Mark this so that we don't latch more than one SMI. */ + /* Mark this so that we don't latch more than one SMI. */ #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SMI while in latched SMM\n"); + x386_common_log("SMI while in latched SMM\n"); #endif } if (smi_line) - smi_line = 0; + smi_line = 0; } - void leave_smm(void) { @@ -1220,45 +1193,45 @@ leave_smm(void) /* If it's a CPU on which SMM is not supported (or not implemented in 86Box), do nothing. */ if (!is_am486 && !is_pentium && !is_k5 && !is_k6 && !is_p6 && !is_cxsmm) - return; + return; memset(saved_state, 0x00, SMM_SAVE_STATE_MAP_SIZE * sizeof(uint32_t)); cpl_override = 1; if (is_cxsmm) { - smram_state = cyrix.smhr & SMHR_ADDR_MASK; - saved_state[0] = readmeml(0, smram_state - 0x04); - saved_state[1] = readmeml(0, smram_state - 0x08); - saved_state[2] = readmeml(0, smram_state - 0x0c); - saved_state[3] = readmeml(0, smram_state - 0x10); - saved_state[4] = readmeml(0, smram_state - 0x14); - saved_state[5] = readmeml(0, smram_state - 0x18); - cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); - saved_state[6] = readmeml(0, smram_state - 0x24); + smram_state = cyrix.smhr & SMHR_ADDR_MASK; + saved_state[0] = readmeml(0, smram_state - 0x04); + saved_state[1] = readmeml(0, smram_state - 0x08); + saved_state[2] = readmeml(0, smram_state - 0x0c); + saved_state[3] = readmeml(0, smram_state - 0x10); + saved_state[4] = readmeml(0, smram_state - 0x14); + saved_state[5] = readmeml(0, smram_state - 0x18); + cyrix_load_seg_descriptor(smram_state - 0x20, &cpu_state.seg_cs); + saved_state[6] = readmeml(0, smram_state - 0x24); } else { - for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { - smram_state -= 4; - saved_state[n] = readmeml(0, smram_state); - x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); - } + for (n = 0; n < SMM_SAVE_STATE_MAP_SIZE; n++) { + smram_state -= 4; + saved_state[n] = readmeml(0, smram_state); + x386_common_log("Reading %08X from memory at %08X to array element %i\n", saved_state[n], smram_state, n); + } } cpl_override = 0; if (unmask_a20_in_smm) { - rammask = old_rammask; + rammask = old_rammask; - flushmmucache(); + flushmmucache(); } x386_common_log("New SMBASE: %08X (%08X)\n", saved_state[SMRAM_FIELD_P5_SMBASE_OFFSET], saved_state[66]); - if (is_cxsmm) /* Cx6x86 */ - smram_restore_state_cyrix(saved_state); - else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ - smram_restore_state_p5(saved_state); - else if (is_k5 || is_k6) /* AMD K5 and K6 */ - smram_restore_state_amd_k(saved_state); - else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ - smram_restore_state_p6(saved_state); + if (is_cxsmm) /* Cx6x86 */ + smram_restore_state_cyrix(saved_state); + else if (is_pentium || is_am486) /* Am486 / 5x86 / Intel P5 (Pentium) */ + smram_restore_state_p5(saved_state); + else if (is_k5 || is_k6) /* AMD K5 and K6 */ + smram_restore_state_amd_k(saved_state); + else if (is_p6) /* Intel P6 (Pentium Pro, Pentium II, Celeron) */ + smram_restore_state_p6(saved_state); in_smm = 0; smram_recalc_all(1); @@ -1266,9 +1239,9 @@ leave_smm(void) cpu_386_flags_extract(); cpu_cur_status &= ~(CPU_STATUS_PMODE | CPU_STATUS_V86); if (cr0 & 1) { - cpu_cur_status |= CPU_STATUS_PMODE; - if (cpu_state.eflags & VM_FLAG) - cpu_cur_status |= CPU_STATUS_V86; + cpu_cur_status |= CPU_STATUS_PMODE; + if (cpu_state.eflags & VM_FLAG) + cpu_cur_status |= CPU_STATUS_V86; } nmi_mask = 1; @@ -1278,90 +1251,88 @@ leave_smm(void) CPU_BLOCK_END(); x386_common_log("CS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, - cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); + cpu_state.seg_cs.seg, cpu_state.seg_cs.base, cpu_state.seg_cs.limit, cpu_state.seg_cs.limit_low, + cpu_state.seg_cs.limit_high, cpu_state.seg_cs.access, cpu_state.seg_cs.ar_high); x386_common_log("DS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, - cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); + cpu_state.seg_ds.seg, cpu_state.seg_ds.base, cpu_state.seg_ds.limit, cpu_state.seg_ds.limit_low, + cpu_state.seg_ds.limit_high, cpu_state.seg_ds.access, cpu_state.seg_ds.ar_high); x386_common_log("ES : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, - cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); + cpu_state.seg_es.seg, cpu_state.seg_es.base, cpu_state.seg_es.limit, cpu_state.seg_es.limit_low, + cpu_state.seg_es.limit_high, cpu_state.seg_es.access, cpu_state.seg_es.ar_high); x386_common_log("FS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, - cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); + cpu_state.seg_fs.seg, cpu_state.seg_fs.base, cpu_state.seg_fs.limit, cpu_state.seg_fs.limit_low, + cpu_state.seg_fs.limit_high, cpu_state.seg_fs.access, cpu_state.seg_fs.ar_high); x386_common_log("GS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, - cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); + cpu_state.seg_gs.seg, cpu_state.seg_gs.base, cpu_state.seg_gs.limit, cpu_state.seg_gs.limit_low, + cpu_state.seg_gs.limit_high, cpu_state.seg_gs.access, cpu_state.seg_gs.ar_high); x386_common_log("SS : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, - cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); + cpu_state.seg_ss.seg, cpu_state.seg_ss.base, cpu_state.seg_ss.limit, cpu_state.seg_ss.limit_low, + cpu_state.seg_ss.limit_high, cpu_state.seg_ss.access, cpu_state.seg_ss.ar_high); x386_common_log("TR : seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); + tr.seg, tr.base, tr.limit, tr.limit_low, tr.limit_high, tr.access, tr.ar_high); x386_common_log("LDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); + ldt.seg, ldt.base, ldt.limit, ldt.limit_low, ldt.limit_high, ldt.access, ldt.ar_high); x386_common_log("GDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); + gdt.seg, gdt.base, gdt.limit, gdt.limit_low, gdt.limit_high, gdt.access, gdt.ar_high); x386_common_log("IDT: seg = %04X, base = %08X, limit = %08X, limit_low = %08X, limit_high = %08X, access = %02X, ar_high = %02X\n", - idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); + idt.seg, idt.base, idt.limit, idt.limit_low, idt.limit_high, idt.access, idt.ar_high); x386_common_log("CR0 = %08X, CR3 = %08X, CR4 = %08X, DR6 = %08X, DR7 = %08X\n", cr0, cr3, cr4, dr[6], dr[7]); x386_common_log("EIP = %08X, EFLAGS = %04X%04X\n", cpu_state.pc, cpu_state.eflags, cpu_state.flags); x386_common_log("EAX = %08X, EBX = %08X, ECX = %08X, EDX = %08X, ESI = %08X, EDI = %08X, ESP = %08X, EBP = %08X\n", - EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); + EAX, EBX, ECX, EDX, ESI, EDI, ESP, EBP); x386_common_log("leave_smm()\n"); } - void x86_int(int num) { uint32_t addr; flags_rebuild(); - cpu_state.pc=cpu_state.oldpc; + cpu_state.pc = cpu_state.oldpc; - if (msw&1) - pmodeint(num,0); + if (msw & 1) + pmodeint(num, 0); else { - addr = (num << 2) + idt.base; + addr = (num << 2) + idt.base; - if ((num << 2UL) + 3UL > idt.limit) { - if (idt.limit < 35) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); + if ((num << 2UL) + 3UL > idt.limit) { + if (idt.limit < 35) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); #ifdef ENABLE_386_COMMON_LOG - x386_common_log("Triple fault in real mode - reset\n"); + x386_common_log("Triple fault in real mode - reset\n"); #endif - } else - x86_int(8); - } else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + } else + x86_int(8); + } else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - } + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + } } cycles -= 70; CPU_BLOCK_END(); } - void x86_int_sw(int num) { @@ -1370,42 +1341,41 @@ x86_int_sw(int num) flags_rebuild(); cycles -= timing_int; - if (msw&1) - pmodeint(num,1); + if (msw & 1) + pmodeint(num, 1); else { - addr = (num << 2) + idt.base; + addr = (num << 2) + idt.base; - if ((num << 2UL) + 3UL > idt.limit) - x86_int(0x0d); - else { - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xFFFF), CS); - writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); - SP -= 6; - } + if ((num << 2UL) + 3UL > idt.limit) + x86_int(0x0d); + else { + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xFFFF), CS); + writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~T_FLAG; + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~T_FLAG; #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - cycles -= timing_int_rm; - } + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + cycles -= timing_int_rm; + } } trap = 0; CPU_BLOCK_END(); } - int x86_int_sw_rm(int num) { @@ -1415,23 +1385,23 @@ x86_int_sw_rm(int num) flags_rebuild(); cycles -= timing_int; - addr = num << 2; + addr = num << 2; new_pc = readmemw(0, addr); new_cs = readmemw(0, addr + 2); if (cpu_state.abrt) - return 1; + return 1; writememw(ss, ((SP - 2) & 0xFFFF), cpu_state.flags); if (cpu_state.abrt) - return 1; + return 1; writememw(ss, ((SP - 4) & 0xFFFF), CS); writememw(ss, ((SP - 6) & 0xFFFF), cpu_state.pc); if (cpu_state.abrt) - return 1; + return 1; SP -= 6; @@ -1450,49 +1420,47 @@ x86_int_sw_rm(int num) return 0; } - void x86illegal(void) { x86_int(6); } - int checkio(uint32_t port) { uint16_t t; - uint8_t d; + uint8_t d; cpl_override = 1; - t = readmemw(tr.base, 0x66); + t = readmemw(tr.base, 0x66); cpl_override = 0; if (cpu_state.abrt) - return 0; + return 0; if ((t + (port >> 3UL)) > tr.limit) - return 1; + return 1; cpl_override = 1; - d = readmembl(tr.base + t + (port >> 3)); + d = readmembl(tr.base + t + (port >> 3)); cpl_override = 0; return d & (1 << (port & 7)); } - #ifdef OLD_DIVEXCP -#define divexcp() { \ - x386_common_log("Divide exception at %04X(%06X):%04X\n",CS,cs,cpu_state.pc); \ - x86_int(0); \ -} +# define divexcp() \ + { \ + x386_common_log("Divide exception at %04X(%06X):%04X\n", CS, cs, cpu_state.pc); \ + x86_int(0); \ + } #else -#define divexcp() { \ - x86de(NULL, 0); \ -} +# define divexcp() \ + { \ + x86de(NULL, 0); \ + } #endif - int divl(uint32_t val) { @@ -1500,18 +1468,18 @@ divl(uint32_t val) uint32_t rem, quo32; if (val == 0) { - divexcp(); - return 1; + divexcp(); + return 1; } - num = (((uint64_t) EDX) << 32) | EAX; - quo = num / val; - rem = num % val; - quo32=(uint32_t)(quo&0xFFFFFFFF); + num = (((uint64_t) EDX) << 32) | EAX; + quo = num / val; + rem = num % val; + quo32 = (uint32_t) (quo & 0xFFFFFFFF); if (quo != (uint64_t) quo32) { - divexcp(); - return 1; + divexcp(); + return 1; } EDX = rem; @@ -1520,26 +1488,25 @@ divl(uint32_t val) return 0; } - int idivl(int32_t val) { int64_t num, quo; int32_t rem, quo32; - if (val == 0) { - divexcp(); - return 1; + if (val == 0) { + divexcp(); + return 1; } - num = (((uint64_t) EDX) << 32) | EAX; - quo = num / val; - rem = num % val; + num = (((uint64_t) EDX) << 32) | EAX; + quo = num / val; + rem = num % val; quo32 = (int32_t) (quo & 0xFFFFFFFF); if (quo != (int64_t) quo32) { - divexcp(); - return 1; + divexcp(); + return 1; } EDX = rem; @@ -1548,21 +1515,18 @@ idivl(int32_t val) return 0; } - void cpu_386_flags_extract(void) { flags_extract(); } - void cpu_386_flags_rebuild(void) { flags_rebuild(); } - int sysenter(uint32_t fetchdat) { @@ -1572,18 +1536,18 @@ sysenter(uint32_t fetchdat) if (!(msw & 1)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSENTER: CPU not in protected mode"); + x386_common_log("SYSENTER: CPU not in protected mode"); #endif - x86gpf("SYSENTER: CPU not in protected mode", 0); - return cpu_state.abrt; + x86gpf("SYSENTER: CPU not in protected mode", 0); + return cpu_state.abrt; } if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSENTER: CS MSR is zero"); + x386_common_log("SYSENTER: CS MSR is zero"); #endif - x86gpf("SYSENTER: CS MSR is zero", 0); - return cpu_state.abrt; + x86gpf("SYSENTER: CS MSR is zero", 0); + return cpu_state.abrt; } #ifdef ENABLE_386_COMMON_LOG @@ -1602,33 +1566,33 @@ sysenter(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = msr.sysenter_esp; - cpu_state.pc = msr.sysenter_eip; + ESP = msr.sysenter_esp; + cpu_state.pc = msr.sysenter_eip; - cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.seg = (msr.sysenter_cs & 0xfffc); + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x9b; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.access = 0x9b; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; - cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.seg = ((msr.sysenter_cs + 8) & 0xfffc); + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x93; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0x93; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS | CPU_STATUS_V86); - cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32/* | CPU_STATUS_PMODE*/); + cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 /* | CPU_STATUS_PMODE*/); set_use32(1); set_stack32(1); @@ -1645,7 +1609,6 @@ sysenter(uint32_t fetchdat) return 1; } - int sysexit(uint32_t fetchdat) { @@ -1655,26 +1618,26 @@ sysexit(uint32_t fetchdat) if (!(msr.sysenter_cs & 0xFFF8)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CS MSR is zero"); + x386_common_log("SYSEXIT: CS MSR is zero"); #endif - x86gpf("SYSEXIT: CS MSR is zero", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CS MSR is zero", 0); + return cpu_state.abrt; } if (!(msw & 1)) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CPU not in protected mode"); + x386_common_log("SYSEXIT: CPU not in protected mode"); #endif - x86gpf("SYSEXIT: CPU not in protected mode", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CPU not in protected mode", 0); + return cpu_state.abrt; } if (CPL) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSEXIT: CPL not 0"); + x386_common_log("SYSEXIT: CPL not 0"); #endif - x86gpf("SYSEXIT: CPL not 0", 0); - return cpu_state.abrt; + x86gpf("SYSEXIT: CPL not 0", 0); + return cpu_state.abrt; } #ifdef ENABLE_386_COMMON_LOG @@ -1689,32 +1652,32 @@ sysexit(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ESP = ECX; - cpu_state.pc = EDX; + ESP = ECX; + cpu_state.pc = EDX; - cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + cpu_state.seg_cs.seg = (((msr.sysenter_cs + 16) & 0xfffc) | 3); + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0xfb; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.access = 0xfb; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; - cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + cpu_state.seg_ss.seg = (((msr.sysenter_cs + 24) & 0xfffc) | 3); + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0xf3; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0xf3; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS/* | CPU_STATUS_V86*/); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/); cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); flushmmucache_cr3(); set_use32(1); @@ -1733,7 +1696,6 @@ sysexit(uint32_t fetchdat) return 1; } - int syscall_op(uint32_t fetchdat) { @@ -1750,28 +1712,28 @@ syscall_op(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - ECX = cpu_state.pc; + ECX = cpu_state.pc; /* CS */ - CS = AMD_SYSCALL_SB & 0xfffc; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + CS = AMD_SYSCALL_SB & 0xfffc; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0x9b; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 0; + cpu_state.seg_cs.access = 0x9b; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 0; /* SS */ - SS = (AMD_SYSCALL_SB + 8) & 0xfffc; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + SS = (AMD_SYSCALL_SB + 8) & 0xfffc; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0x93; - cpu_state.seg_ss.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0x93; + cpu_state.seg_ss.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif @@ -1786,7 +1748,6 @@ syscall_op(uint32_t fetchdat) return 1; } - int sysret(uint32_t fetchdat) { @@ -1796,10 +1757,10 @@ sysret(uint32_t fetchdat) if (CPL) { #ifdef ENABLE_386_COMMON_LOG - x386_common_log("SYSRET: CPL not 0"); + x386_common_log("SYSRET: CPL not 0"); #endif - x86gpf("SYSRET: CPL not 0", 0); - return cpu_state.abrt; + x86gpf("SYSRET: CPL not 0", 0); + return cpu_state.abrt; } cpu_state.flags |= I_FLAG; @@ -1811,33 +1772,33 @@ sysret(uint32_t fetchdat) oldcs = CS; #endif cpu_state.oldpc = cpu_state.pc; - cpu_state.pc = ECX; + cpu_state.pc = ECX; /* CS */ - CS = (AMD_SYSRET_SB & 0xfffc) | 3; - cpu_state.seg_cs.base = 0; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit = 0xffffffff; + CS = (AMD_SYSRET_SB & 0xfffc) | 3; + cpu_state.seg_cs.base = 0; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit = 0xffffffff; cpu_state.seg_cs.limit_high = 0xffffffff; - cpu_state.seg_cs.access = 0xfb; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_cs.checked = 1; - oldcpl = 3; + cpu_state.seg_cs.access = 0xfb; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_cs.checked = 1; + oldcpl = 3; /* SS */ - SS = ((AMD_SYSRET_SB + 8) & 0xfffc) | 3; - cpu_state.seg_ss.base = 0; - cpu_state.seg_ss.limit_low = 0; - cpu_state.seg_ss.limit = 0xffffffff; + SS = ((AMD_SYSRET_SB + 8) & 0xfffc) | 3; + cpu_state.seg_ss.base = 0; + cpu_state.seg_ss.limit_low = 0; + cpu_state.seg_ss.limit = 0xffffffff; cpu_state.seg_ss.limit_high = 0xffffffff; - cpu_state.seg_ss.access = 0xf3; - cpu_state.seg_cs.ar_high = 0xcf; - cpu_state.seg_ss.checked = 1; + cpu_state.seg_ss.access = 0xf3; + cpu_state.seg_cs.ar_high = 0xcf; + cpu_state.seg_ss.checked = 1; #ifdef USE_DYNAREC codegen_flat_ss = 0; #endif - cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS/* | CPU_STATUS_V86*/); + cpu_cur_status &= ~(CPU_STATUS_NOTFLATSS /* | CPU_STATUS_V86*/); cpu_cur_status |= (CPU_STATUS_USE32 | CPU_STATUS_STACK32 | CPU_STATUS_PMODE); flushmmucache_cr3(); set_use32(1); @@ -1848,23 +1809,20 @@ sysret(uint32_t fetchdat) return 1; } - void cpu_register_fast_off_handler(void *timer) { cpu_fast_off_timer = (pc_timer_t *) timer; } - void cpu_fast_off_advance(void) { timer_disable(cpu_fast_off_timer); if (cpu_fast_off_period != 0.0) - timer_on_auto(cpu_fast_off_timer, cpu_fast_off_period); + timer_on_auto(cpu_fast_off_timer, cpu_fast_off_period); } - void cpu_fast_off_period_set(uint16_t val, double period) { @@ -1872,7 +1830,6 @@ cpu_fast_off_period_set(uint16_t val, double period) cpu_fast_off_advance(); } - void cpu_fast_off_reset(void) { @@ -1881,31 +1838,29 @@ cpu_fast_off_reset(void) cpu_fast_off_advance(); } - void smi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x80000000)) - cpu_fast_off_advance(); + cpu_fast_off_advance(); smi_line = 1; } - void nmi_raise(void) { if (is486 && (cpu_fast_off_flags & 0x20000000)) - cpu_fast_off_advance(); + cpu_fast_off_advance(); nmi = 1; } - #ifndef USE_DYNAREC /* This is for compatibility with new x87 code. */ -void codegen_set_rounding_mode(int mode) +void +codegen_set_rounding_mode(int mode) { - /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); */ + /* cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00) | (mode << 10); */ } #endif diff --git a/src/cpu/386_common.h b/src/cpu/386_common.h index f99c143d9..6310ae642 100644 --- a/src/cpu/386_common.h +++ b/src/cpu/386_common.h @@ -21,308 +21,400 @@ #include -#define readmemb_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl_no_mmut((s)+(a),b): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl_no_mmut((s)+(a),b):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml_n(s,a,b) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll_no_mmut((s)+(a),b):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF)?readmembl((s)+(a)): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uintptr_t)((s) + (a))) ) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl((s)+(a)):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll((s)+(a)):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql((s)+(a)):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uintptr_t)((s)+(a)))) +#define readmemb_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl_no_mmut((s) + (a), b) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#define readmemw_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl_no_mmut((s) + (a), b) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmeml_n(s, a, b) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll_no_mmut((s) + (a), b) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmemb(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) ? readmembl((s) + (a)) : *(uint8_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) +#define readmemw(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) ? readmemwl((s) + (a)) : *(uint16_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmeml(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) ? readmemll((s) + (a)) : *(uint32_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uint32_t) ((s) + (a)))) +#define readmemq(s, a) ((readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) ? readmemql((s) + (a)) : *(uint64_t *) (readlookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a)))) -#define writememb_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl_no_mmut((s)+(a),b,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl_no_mmut((s)+(a),b,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl_n(s,a,b,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll_no_mmut((s)+(a),b,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) writemembl((s)+(a),v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl((s)+(a),v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll((s)+(a),v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql((s)+(a),v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uintptr_t)((s) + (a))) = v +#define writememb_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl_no_mmut((s) + (a), b, v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememw_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl_no_mmut((s) + (a), b, v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememl_n(s, a, b, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll_no_mmut((s) + (a), b, v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememb(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + writemembl((s) + (a), v); \ + else \ + *(uint8_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememw(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + writememwl((s) + (a), v); \ + else \ + *(uint16_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememl(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + writememll((s) + (a), v); \ + else \ + *(uint32_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v +#define writememq(s, a, v) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 7)) \ + writememql((s) + (a), v); \ + else \ + *(uint64_t *) (writelookup2[(uint32_t) ((s) + (a)) >> 12] + (uintptr_t) ((s) + (a))) = v -#define do_mmut_rb(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl(s,a,b) if (readlookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) -#define do_mmut_rb2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 0) -#define do_mmut_rw2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 0) -#define do_mmut_rl2(s,a,b) old_rl2 = readlookup2[(uint32_t)((s)+(a))>>12]; if (old_rl2==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 0) - -#define do_mmut_wb(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF) do_mmutranslate((s)+(a), b, 1, 1) -#define do_mmut_ww(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) do_mmutranslate((s)+(a), b, 2, 1) -#define do_mmut_wl(s,a,b) if (writelookup2[(uint32_t)((s)+(a))>>12]==(uintptr_t)LOOKUP_INV || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) do_mmutranslate((s)+(a), b, 4, 1) +#define do_mmut_rb(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +#define do_mmut_rw(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +#define do_mmut_rl(s, a, b) \ + if (readlookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +#define do_mmut_rb2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 0) +#define do_mmut_rw2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 0) +#define do_mmut_rl2(s, a, b) \ + old_rl2 = readlookup2[(uint32_t) ((s) + (a)) >> 12]; \ + if (old_rl2 == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 0) +#define do_mmut_wb(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF) \ + do_mmutranslate((s) + (a), b, 1, 1) +#define do_mmut_ww(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 1)) \ + do_mmutranslate((s) + (a), b, 2, 1) +#define do_mmut_wl(s, a, b) \ + if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \ + do_mmutranslate((s) + (a), b, 4, 1) int checkio(uint32_t port); +#define check_io_perm(port) \ + if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \ + int tempi = checkio(port); \ + if (cpu_state.abrt) \ + return 1; \ + if (tempi) { \ + if (cpu_state.eflags & VM_FLAG) \ + x86gpf_expected(NULL, 0); \ + else \ + x86gpf(NULL, 0); \ + return 1; \ + } \ + } -#define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (cpu_state.eflags&VM_FLAG))) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - if (cpu_state.eflags & VM_FLAG) \ - x86gpf_expected(NULL,0); \ - else \ - x86gpf(NULL,0); \ - return 1; \ - } \ - } +#define SEG_CHECK_READ(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't read", 0); \ + return 1; \ + } \ + } while (0) -#define SEG_CHECK_READ(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't read", 0);\ - return 1; \ - } \ - } while (0) +#define SEG_CHECK_WRITE(seg) \ + do { \ + if ((seg)->base == 0xffffffff) { \ + x86gpf("Segment can't write", 0); \ + return 1; \ + } \ + } while (0) -#define SEG_CHECK_WRITE(seg) \ - do \ - { \ - if ((seg)->base == 0xffffffff) \ - { \ - x86gpf("Segment can't write", 0);\ - return 1; \ - } \ - } while (0) +#define CHECK_READ(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) { \ + x86gpf("Limit check (READ)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } -#define CHECK_READ(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \ - { \ - x86gpf("Limit check (READ)", 0); \ - return 1; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } +#define CHECK_READ_REP(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ + x86gpf("Limit check (READ)", 0); \ + break; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ + break; \ + } -#define CHECK_READ_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (READ)", 0); \ - break; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Read from seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } +#define CHECK_WRITE_COMMON(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) { \ + x86gpf("Limit check (WRITE)", 0); \ + return 1; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ + return 1; \ + } -#define CHECK_WRITE_COMMON(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(cpu_state.eflags & VM_FLAG) && ((chseg)->access & 8))) \ - { \ - x86gpf("Limit check (WRITE)", 0); \ - return 1; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write to seg not present", (chseg)->seg & 0xfffc); \ - return 1; \ - } +#define CHECK_WRITE(chseg, low, high) \ + CHECK_WRITE_COMMON(chseg, low, high) -#define CHECK_WRITE(chseg, low, high) \ - CHECK_WRITE_COMMON(chseg, low, high) +#define CHECK_WRITE_REP(chseg, low, high) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) { \ + x86gpf("Limit check (WRITE REP)", 0); \ + break; \ + } \ + if (msw & 1 && !(cpu_state.eflags & VM_FLAG) && !((chseg)->access & 0x80)) { \ + if ((chseg) == &cpu_state.seg_ss) \ + x86ss(NULL, (chseg)->seg & 0xfffc); \ + else \ + x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ + break; \ + } -#define CHECK_WRITE_REP(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ - { \ - x86gpf("Limit check (WRITE REP)", 0); \ - break; \ - } \ - if (msw&1 && !(cpu_state.eflags&VM_FLAG) && !((chseg)->access & 0x80)) \ - { \ - if ((chseg) == &cpu_state.seg_ss) \ - x86ss(NULL,(chseg)->seg & 0xfffc); \ - else \ - x86np("Write (REP) to seg not present", (chseg)->seg & 0xfffc); \ - break; \ - } +#define NOTRM \ + if (!(msw & 1) || (cpu_state.eflags & VM_FLAG)) { \ + x86_int(6); \ + return 1; \ + } - -#define NOTRM if (!(msw & 1) || (cpu_state.eflags & VM_FLAG))\ - { \ - x86_int(6); \ - return 1; \ - } - - - - -static __inline uint8_t fastreadb(uint32_t a) +static __inline uint8_t +fastreadb(uint32_t a) { - uint8_t *t; + uint8_t *t; - if ((a >> 12) == pccache) - return *((uint8_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache = a >> 12; - pccache2 = t; - return *((uint8_t *)&pccache2[a]); + if ((a >> 12) == pccache) + return *((uint8_t *) &pccache2[a]); + t = getpccache(a); + if (cpu_state.abrt) + return 0; + pccache = a >> 12; + pccache2 = t; + return *((uint8_t *) &pccache2[a]); } -static __inline uint16_t fastreadw(uint32_t a) +static __inline uint16_t +fastreadw(uint32_t a) { - uint8_t *t; - uint16_t val; - if ((a&0xFFF)>0xFFE) - { - val = fastreadb(a); - val |= (fastreadb(a + 1) << 8); - return val; - } - if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); - t = getpccache(a); - if (cpu_state.abrt) - return 0; - - pccache = a >> 12; - pccache2 = t; - return *((uint16_t *)&pccache2[a]); -} - -static __inline uint32_t fastreadl(uint32_t a) -{ - uint8_t *t; - uint32_t val; - if ((a&0xFFF)<0xFFD) - { - if ((a>>12)!=pccache) - { - t = getpccache(a); - if (cpu_state.abrt) - return 0; - pccache2 = t; - pccache=a>>12; - } - return *((uint32_t *)&pccache2[a]); - } - val = fastreadw(a); - val |= (fastreadw(a + 2) << 16); + uint8_t *t; + uint16_t val; + if ((a & 0xFFF) > 0xFFE) { + val = fastreadb(a); + val |= (fastreadb(a + 1) << 8); return val; + } + if ((a >> 12) == pccache) + return *((uint16_t *) &pccache2[a]); + t = getpccache(a); + if (cpu_state.abrt) + return 0; + + pccache = a >> 12; + pccache2 = t; + return *((uint16_t *) &pccache2[a]); } -static __inline void *get_ram_ptr(uint32_t a) +static __inline uint32_t +fastreadl(uint32_t a) { - if ((a >> 12) == pccache) - return &pccache2[a]; - else - { - uint8_t *t = getpccache(a); - return &t[a]; + uint8_t *t; + uint32_t val; + if ((a & 0xFFF) < 0xFFD) { + if ((a >> 12) != pccache) { + t = getpccache(a); + if (cpu_state.abrt) + return 0; + pccache2 = t; + pccache = a >> 12; } + return *((uint32_t *) &pccache2[a]); + } + val = fastreadw(a); + val |= (fastreadw(a + 2) << 16); + return val; } -static __inline uint8_t getbyte(void) +static __inline void * +get_ram_ptr(uint32_t a) { - cpu_state.pc++; - return fastreadb(cs + (cpu_state.pc - 1)); + if ((a >> 12) == pccache) + return &pccache2[a]; + else { + uint8_t *t = getpccache(a); + return &t[a]; + } } -static __inline uint16_t getword(void) +static __inline uint8_t +getbyte(void) { - cpu_state.pc+=2; - return fastreadw(cs+(cpu_state.pc-2)); + cpu_state.pc++; + return fastreadb(cs + (cpu_state.pc - 1)); } -static __inline uint32_t getlong(void) +static __inline uint16_t +getword(void) { - cpu_state.pc+=4; - return fastreadl(cs+(cpu_state.pc-4)); + cpu_state.pc += 2; + return fastreadw(cs + (cpu_state.pc - 2)); } -static __inline uint64_t getquad(void) +static __inline uint32_t +getlong(void) { - cpu_state.pc+=8; - return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32); + cpu_state.pc += 4; + return fastreadl(cs + (cpu_state.pc - 4)); } - - -static __inline uint8_t geteab(void) +static __inline uint64_t +getquad(void) { - if (cpu_mod == 3) - return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l; - if (eal_r) - return *(uint8_t *)eal_r; - return readmemb(easeg, cpu_state.eaaddr); + cpu_state.pc += 8; + return fastreadl(cs + (cpu_state.pc - 8)) | ((uint64_t) fastreadl(cs + (cpu_state.pc - 4)) << 32); } -static __inline uint16_t geteaw(void) +static __inline uint8_t +geteab(void) { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].w; - if (eal_r) - return *(uint16_t *)eal_r; - return readmemw(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; + if (eal_r) + return *(uint8_t *) eal_r; + return readmemb(easeg, cpu_state.eaaddr); } -static __inline uint32_t geteal(void) +static __inline uint16_t +geteaw(void) { - if (cpu_mod == 3) - return cpu_state.regs[cpu_rm].l; - if (eal_r) - return *eal_r; - return readmeml(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].w; + if (eal_r) + return *(uint16_t *) eal_r; + return readmemw(easeg, cpu_state.eaaddr); } -static __inline uint64_t geteaq(void) +static __inline uint32_t +geteal(void) { - return readmemq(easeg, cpu_state.eaaddr); + if (cpu_mod == 3) + return cpu_state.regs[cpu_rm].l; + if (eal_r) + return *eal_r; + return readmeml(easeg, cpu_state.eaaddr); } -static __inline uint8_t geteab_mem(void) +static __inline uint64_t +geteaq(void) { - if (eal_r) return *(uint8_t *)eal_r; - return readmemb(easeg,cpu_state.eaaddr); + return readmemq(easeg, cpu_state.eaaddr); } -static __inline uint16_t geteaw_mem(void) + +static __inline uint8_t +geteab_mem(void) { - if (eal_r) return *(uint16_t *)eal_r; - return readmemw(easeg,cpu_state.eaaddr); + if (eal_r) + return *(uint8_t *) eal_r; + return readmemb(easeg, cpu_state.eaaddr); } -static __inline uint32_t geteal_mem(void) +static __inline uint16_t +geteaw_mem(void) { - if (eal_r) return *eal_r; - return readmeml(easeg,cpu_state.eaaddr); + if (eal_r) + return *(uint16_t *) eal_r; + return readmemw(easeg, cpu_state.eaaddr); } - -static __inline int seteaq_cwc(void) +static __inline uint32_t +geteal_mem(void) { - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - return 0; + if (eal_r) + return *eal_r; + return readmeml(easeg, cpu_state.eaaddr); } -static __inline void seteaq(uint64_t v) +static __inline int +seteaq_cwc(void) { - if (seteaq_cwc()) - return; - writememql(easeg + cpu_state.eaaddr, v); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + return 0; } -#define seteab(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); } else if (cpu_rm&4) cpu_state.regs[cpu_rm&3].b.h=v; else cpu_state.regs[cpu_rm].b.l=v -#define seteaw(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].w=v -#define seteal(v) if (cpu_mod!=3) { CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); } else cpu_state.regs[cpu_rm].l=v +static __inline void +seteaq(uint64_t v) +{ + if (seteaq_cwc()) + return; + writememql(easeg + cpu_state.eaaddr, v); +} -#define seteab_mem(v) if (eal_w) *(uint8_t *)eal_w=v; else writemembl(easeg+cpu_state.eaaddr,v); -#define seteaw_mem(v) if (eal_w) *(uint16_t *)eal_w=v; else writememwl(easeg+cpu_state.eaaddr,v); -#define seteal_mem(v) if (eal_w) *eal_w=v; else writememll(easeg+cpu_state.eaaddr,v); +#define seteab(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); \ + } else if (cpu_rm & 4) \ + cpu_state.regs[cpu_rm & 3].b.h = v; \ + else \ + cpu_state.regs[cpu_rm].b.l = v +#define seteaw(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].w = v +#define seteal(v) \ + if (cpu_mod != 3) { \ + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); \ + } else \ + cpu_state.regs[cpu_rm].l = v -#define getbytef() ((uint8_t)(fetchdat)); cpu_state.pc++ -#define getwordf() ((uint16_t)(fetchdat)); cpu_state.pc+=2 -#define getbyte2f() ((uint8_t)(fetchdat>>8)); cpu_state.pc++ -#define getword2f() ((uint16_t)(fetchdat>>8)); cpu_state.pc+=2 +#define seteab_mem(v) \ + if (eal_w) \ + *(uint8_t *) eal_w = v; \ + else \ + writemembl(easeg + cpu_state.eaaddr, v); +#define seteaw_mem(v) \ + if (eal_w) \ + *(uint16_t *) eal_w = v; \ + else \ + writememwl(easeg + cpu_state.eaaddr, v); +#define seteal_mem(v) \ + if (eal_w) \ + *eal_w = v; \ + else \ + writememll(easeg + cpu_state.eaaddr, v); + +#define getbytef() \ + ((uint8_t) (fetchdat)); \ + cpu_state.pc++ +#define getwordf() \ + ((uint16_t) (fetchdat)); \ + cpu_state.pc += 2 +#define getbyte2f() \ + ((uint8_t) (fetchdat >> 8)); \ + cpu_state.pc++ +#define getword2f() \ + ((uint16_t) (fetchdat >> 8)); \ + cpu_state.pc += 2 #endif diff --git a/src/cpu/386_dynarec.c b/src/cpu/386_dynarec.c index fb3534c9a..f2e04b54a 100644 --- a/src/cpu/386_dynarec.c +++ b/src/cpu/386_dynarec.c @@ -4,12 +4,12 @@ #include #include #if defined(__APPLE__) && defined(__aarch64__) -#include +# include #endif #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #define HAVE_STDARG_H @@ -28,164 +28,161 @@ #include <86box/machine.h> #include <86box/gdbstub.h> #ifdef USE_DYNAREC -#include "codegen.h" -#ifdef USE_NEW_DYNAREC -#include "codegen_backend.h" -#endif +# include "codegen.h" +# ifdef USE_NEW_DYNAREC +# include "codegen_backend.h" +# endif #endif #ifdef IS_DYNAREC -#undef IS_DYNAREC +# undef IS_DYNAREC #endif #include "386_common.h" #if defined(__APPLE__) && defined(__aarch64__) -#include +# include #endif #define CPU_BLOCK_END() cpu_block_end = 1 - int inrecomp = 0, cpu_block_end = 0; int cpu_end_block_after_ins = 0; - #ifdef ENABLE_386_DYNAREC_LOG int x386_dynarec_do_log = ENABLE_386_DYNAREC_LOG; - void x386_dynarec_log(const char *fmt, ...) { va_list ap; if (x386_dynarec_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x386_dynarec_log(fmt, ...) +# define x386_dynarec_log(fmt, ...) #endif - -static __inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void +fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (cpu_rm == 4) - { - uint8_t sib = rmdat >> 8; + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (cpu_rm == 4) { + uint8_t sib = rmdat >> 8; - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = cpu_state.regs[sib & 7].l; - cpu_state.pc++; - break; - case 1: - cpu_state.pc++; - cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; - break; - case 2: - cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; - cpu_state.pc += 5; - break; - } - /*SIB byte present*/ - if ((sib & 7) == 5 && !cpu_mod) - cpu_state.eaaddr = getlong(); - else if ((sib & 6) == 4 && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (((sib >> 3) & 7) != 4) - cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); - } - else - { - cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; - if (cpu_mod) - { - if (cpu_rm == 5 && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - if (cpu_mod == 1) - { - cpu_state.eaaddr += ((uint32_t)(int8_t)(rmdat >> 8)); - cpu_state.pc++; - } - else - { - cpu_state.eaaddr += getlong(); - } - } - else if (cpu_rm == 5) - { - cpu_state.eaaddr = getlong(); - } - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = cpu_state.regs[sib & 7].l; + cpu_state.pc++; + break; + case 1: + cpu_state.pc++; + cpu_state.eaaddr = ((uint32_t) (int8_t) getbyte()) + cpu_state.regs[sib & 7].l; + break; + case 2: + cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; + cpu_state.pc += 5; + break; + } + /*SIB byte present*/ + if ((sib & 7) == 5 && !cpu_mod) + cpu_state.eaaddr = getlong(); + else if ((sib & 6) == 4 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (((sib >> 3) & 7) != 4) + cpu_state.eaaddr += cpu_state.regs[(sib >> 3) & 7].l << (sib >> 6); + } else { + cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; + if (cpu_mod) { + if (cpu_rm == 5 && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + if (cpu_mod == 1) { + cpu_state.eaaddr += ((uint32_t) (int8_t) (rmdat >> 8)); + cpu_state.pc++; + } else { + cpu_state.eaaddr += getlong(); + } + } else if (cpu_rm == 5) { + cpu_state.eaaddr = getlong(); + } + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -static __inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void +fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (!cpu_mod && cpu_rm == 6) - { - cpu_state.eaaddr = getword(); - } - else - { - switch (cpu_mod) - { - case 0: - cpu_state.eaaddr = 0; - break; - case 1: - cpu_state.eaaddr = (uint16_t)(int8_t)(rmdat >> 8); cpu_state.pc++; - break; - case 2: - cpu_state.eaaddr = getword(); - break; - } - cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); - if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) - { - easeg = ss; - cpu_state.ea_seg = &cpu_state.seg_ss; - } - cpu_state.eaaddr &= 0xFFFF; - } - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if (readlookup2[addr >> 12] != (uintptr_t) -1) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) -1) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (!cpu_mod && cpu_rm == 6) { + cpu_state.eaaddr = getword(); + } else { + switch (cpu_mod) { + case 0: + cpu_state.eaaddr = 0; + break; + case 1: + cpu_state.eaaddr = (uint16_t) (int8_t) (rmdat >> 8); + cpu_state.pc++; + break; + case 2: + cpu_state.eaaddr = getword(); + break; + } + cpu_state.eaaddr += (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + if (mod1seg[cpu_rm] == &ss && !cpu_state.ssegs) { + easeg = ss; + cpu_state.ea_seg = &cpu_state.seg_ss; + } + cpu_state.eaaddr &= 0xFFFF; + } + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) -1) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) -1) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_16_long(rmdat); if (cpu_state.abrt) return 1; } -#define fetch_ea_32(rmdat) cpu_state.pc++; cpu_mod=(rmdat >> 6) & 3; cpu_reg=(rmdat >> 3) & 7; cpu_rm = rmdat & 7; if (cpu_mod != 3) { fetch_ea_32_long(rmdat); } if (cpu_state.abrt) return 1 +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_16_long(rmdat); \ + if (cpu_state.abrt) \ + return 1; \ + } +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + cpu_mod = (rmdat >> 6) & 3; \ + cpu_reg = (rmdat >> 3) & 7; \ + cpu_rm = rmdat & 7; \ + if (cpu_mod != 3) { \ + fetch_ea_32_long(rmdat); \ + } \ + if (cpu_state.abrt) \ + return 1 #include "x86_flags.h" - /*Prefetch emulation is a fairly simplistic model: - All instruction bytes must be fetched before it starts. - Cycles used for non-instruction memory accesses are counted and subtracted @@ -195,150 +192,145 @@ static __inline void fetch_ea_16_long(uint32_t rmdat) Note that this is only used for 286 / 386 systems. It is disabled when the internal cache on 486+ CPUs is enabled. */ -static int prefetch_bytes = 0; +static int prefetch_bytes = 0; static int prefetch_prefixes = 0; -static void prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) +static void +prefetch_run(int instr_cycles, int bytes, int modrm, int reads, int reads_l, int writes, int writes_l, int ea32) { - int mem_cycles = reads*cpu_cycles_read + reads_l*cpu_cycles_read_l + writes*cpu_cycles_write + writes_l*cpu_cycles_write_l; + int mem_cycles = reads * cpu_cycles_read + reads_l * cpu_cycles_read_l + writes * cpu_cycles_write + writes_l * cpu_cycles_write_l; - if (instr_cycles < mem_cycles) - instr_cycles = mem_cycles; + if (instr_cycles < mem_cycles) + instr_cycles = mem_cycles; - prefetch_bytes -= prefetch_prefixes; - prefetch_bytes -= bytes; - if (modrm != -1) - { - if (ea32) - { - if ((modrm & 7) == 4) - { - if ((modrm & 0x700) == 0x500) - prefetch_bytes -= 5; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 5; - } - else - { - if ((modrm & 0xc7) == 0x05) - prefetch_bytes -= 4; - else if ((modrm & 0xc0) == 0x40) - prefetch_bytes--; - else if ((modrm & 0xc0) == 0x80) - prefetch_bytes -= 4; - } - } - else - { - if ((modrm & 0xc7) == 0x06) - prefetch_bytes -= 2; - else if ((modrm & 0xc0) != 0xc0) - prefetch_bytes -= ((modrm & 0xc0) >> 6); - } - } + prefetch_bytes -= prefetch_prefixes; + prefetch_bytes -= bytes; + if (modrm != -1) { + if (ea32) { + if ((modrm & 7) == 4) { + if ((modrm & 0x700) == 0x500) + prefetch_bytes -= 5; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 5; + } else { + if ((modrm & 0xc7) == 0x05) + prefetch_bytes -= 4; + else if ((modrm & 0xc0) == 0x40) + prefetch_bytes--; + else if ((modrm & 0xc0) == 0x80) + prefetch_bytes -= 4; + } + } else { + if ((modrm & 0xc7) == 0x06) + prefetch_bytes -= 2; + else if ((modrm & 0xc0) != 0xc0) + prefetch_bytes -= ((modrm & 0xc0) >> 6); + } + } - /* Fill up prefetch queue */ - while (prefetch_bytes < 0) - { - prefetch_bytes += cpu_prefetch_width; - cycles -= cpu_prefetch_cycles; - } + /* Fill up prefetch queue */ + while (prefetch_bytes < 0) { + prefetch_bytes += cpu_prefetch_width; + cycles -= cpu_prefetch_cycles; + } - /* Subtract cycles used for memory access by instruction */ - instr_cycles -= mem_cycles; + /* Subtract cycles used for memory access by instruction */ + instr_cycles -= mem_cycles; - while (instr_cycles >= cpu_prefetch_cycles) - { - prefetch_bytes += cpu_prefetch_width; - instr_cycles -= cpu_prefetch_cycles; - } + while (instr_cycles >= cpu_prefetch_cycles) { + prefetch_bytes += cpu_prefetch_width; + instr_cycles -= cpu_prefetch_cycles; + } - prefetch_prefixes = 0; - if (prefetch_bytes > 16) - prefetch_bytes = 16; + prefetch_prefixes = 0; + if (prefetch_bytes > 16) + prefetch_bytes = 16; } -static void prefetch_flush(void) +static void +prefetch_flush(void) { - prefetch_bytes = 0; + prefetch_bytes = 0; } -#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ - do { if (cpu_prefetch_cycles) prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); } while (0) +#define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32) \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_run(instr_cycles, bytes, modrm, reads, reads_l, writes, writes_l, ea32); \ + } while (0) -#define PREFETCH_PREFIX() do { if (cpu_prefetch_cycles) prefetch_prefixes++; } while (0) +#define PREFETCH_PREFIX() \ + do { \ + if (cpu_prefetch_cycles) \ + prefetch_prefixes++; \ + } while (0) #define PREFETCH_FLUSH() prefetch_flush() - -#define OP_TABLE(name) ops_ ## name +#define OP_TABLE(name) ops_##name #if 0 -#define CLOCK_CYCLES(c) \ - {\ - if (fpu_cycles > 0) {\ - fpu_cycles -= (c);\ - if (fpu_cycles < 0) {\ - cycles += fpu_cycles;\ - }\ - } else {\ - cycles -= (c);\ - }\ - } -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES(c) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (c); \ + if (fpu_cycles < 0) { \ + cycles += fpu_cycles; \ + } \ + } else { \ + cycles -= (c); \ + } \ + } +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES(c) cycles -= (c) -#define CLOCK_CYCLES_FPU(c) cycles -= (c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES(c) cycles -= (c) +# define CLOCK_CYCLES_FPU(c) cycles -= (c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) - #include "386_ops.h" - #define CACHE_ON() (!(cr0 & (1 << 30)) && !(cpu_state.flags & T_FLAG)) #ifdef USE_DYNAREC -int cycles_main = 0; -static int cycles_old = 0; -static uint64_t tsc_old = 0; +int cycles_main = 0; +static int cycles_old = 0; +static uint64_t tsc_old = 0; -#ifdef USE_ACYCS +# ifdef USE_ACYCS int acycs = 0; -#endif - +# endif void update_tsc(void) { - int cycdiff; + int cycdiff; uint64_t delta; cycdiff = cycles_old - cycles; -#ifdef USE_ACYCS +# ifdef USE_ACYCS if (inrecomp) - cycdiff += acycs; -#endif + cycdiff += acycs; +# endif delta = tsc - tsc_old; if (delta > 0) { - /* TSC has changed, this means interim timer processing has happened, - see how much we still need to add. */ - cycdiff -= delta; + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; } if (cycdiff > 0) - tsc += cycdiff; + tsc += cycdiff; if (cycdiff > 0) { - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) - timer_process_inline(); + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); } } - static __inline void exec386_dynarec_int(void) { @@ -346,530 +338,523 @@ exec386_dynarec_int(void) x86_was_reset = 0; while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif + fetchdat = fastreadl(cs + cpu_state.pc); +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - trap = cpu_state.flags & T_FLAG; + trap = cpu_state.flags & T_FLAG; - cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - } + cpu_state.pc++; + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - if (((cs + cpu_state.pc) >> 12) != pccache) - CPU_BLOCK_END(); + if (((cs + cpu_state.pc) >> 12) != pccache) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - else if (trap) - CPU_BLOCK_END(); - else if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.abrt) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + else if (trap) + CPU_BLOCK_END(); + else if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + else if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); } if (!cpu_state.abrt && trap) { - trap = 0; -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - dr[6] |= 0x4000; - x86_int(1); + trap = 0; +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + dr[6] |= 0x4000; + x86_int(1); } cpu_end_block_after_ins = 0; } - static __inline void exec386_dynarec_dyn(void) { uint32_t start_pc = 0, phys_addr = get_phys(cs + cpu_state.pc); - int hash = HASH(phys_addr); -#ifdef USE_NEW_DYNAREC + int hash = HASH(phys_addr); +# ifdef USE_NEW_DYNAREC codeblock_t *block = &codeblock[codeblock_hash[hash]]; -#else +# else codeblock_t *block = codeblock_hash[hash]; -#endif +# endif int valid_block = 0; -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC if (!cpu_state.abrt) -#else +# else if (block && !cpu_state.abrt) -#endif +# endif { - page_t *page = &pages[phys_addr >> 12]; + page_t *page = &pages[phys_addr >> 12]; - /* Block must match current CS, PC, code segment size, - and physical address. The physical address check will - also catch any page faults at this stage */ - valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (!valid_block) { - uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); -#ifdef USE_NEW_DYNAREC - int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; - uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); + /* Block must match current CS, PC, code segment size, + and physical address. The physical address check will + also catch any page faults at this stage */ + valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && (block->phys == phys_addr) && !((block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (!valid_block) { + uint64_t mask = (uint64_t) 1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); +# ifdef USE_NEW_DYNAREC + int byte_offset = (phys_addr >> PAGE_BYTE_MASK_SHIFT) & PAGE_BYTE_MASK_OFFSET_MASK; + uint64_t byte_mask = 1ull << (PAGE_BYTE_MASK_MASK & 0x3f); - if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) -#else - if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) -#endif - { - /* Walk page tree to see if we find the correct block */ - codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); - if (new_block) { - valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && - ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); - if (valid_block) { - block = new_block; -#ifdef USE_NEW_DYNAREC - codeblock_hash[hash] = get_block_nr(block); -#endif - } - } - } - } + if ((page->code_present_mask & mask) || (page->byte_code_present_mask[byte_offset] & byte_mask)) +# else + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) +# endif + { + /* Walk page tree to see if we find the correct block */ + codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); + if (new_block) { + valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && (new_block->phys == phys_addr) && !((new_block->status ^ cpu_cur_status) & CPU_STATUS_FLAGS) && ((new_block->status & cpu_cur_status & CPU_STATUS_MASK) == (cpu_cur_status & CPU_STATUS_MASK)); + if (valid_block) { + block = new_block; +# ifdef USE_NEW_DYNAREC + codeblock_hash[hash] = get_block_nr(block); +# endif + } + } + } + } - if (valid_block && (block->page_mask & *block->dirty_mask)) { -#ifdef USE_NEW_DYNAREC - codegen_check_flush(page, page->dirty_mask, phys_addr); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; -#else - codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); - page->dirty_mask[(phys_addr >> 10) & 3] = 0; - if (!block->valid) - valid_block = 0; -#endif - } - if (valid_block && block->page_mask2) { - /* We don't want the second page to cause a page - fault at this stage - that would break any - code crossing a page boundary where the first - page is present but the second isn't. Instead - allow the first page to be interpreted and for - the page fault to occur when the page boundary - is actually crossed.*/ -#ifdef USE_NEW_DYNAREC - uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); -#else - uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); -#endif - page_t *page_2 = &pages[phys_addr_2 >> 12]; + if (valid_block && (block->page_mask & *block->dirty_mask)) { +# ifdef USE_NEW_DYNAREC + codegen_check_flush(page, page->dirty_mask, phys_addr); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +# else + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +# endif + } + if (valid_block && block->page_mask2) { + /* We don't want the second page to cause a page + fault at this stage - that would break any + code crossing a page boundary where the first + page is present but the second isn't. Instead + allow the first page to be interpreted and for + the page fault to occur when the page boundary + is actually crossed.*/ +# ifdef USE_NEW_DYNAREC + uint32_t phys_addr_2 = get_phys_noabrt(block->pc + ((block->flags & CODEBLOCK_BYTE_MASK) ? 0x40 : 0x400)); +# else + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); +# endif + page_t *page_2 = &pages[phys_addr_2 >> 12]; - if ((block->phys_2 ^ phys_addr_2) & ~0xfff) - valid_block = 0; - else if (block->page_mask2 & *block->dirty_mask2) { -#ifdef USE_NEW_DYNAREC - codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); - if (block->pc == BLOCK_PC_INVALID) - valid_block = 0; - else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; -#else - codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); - page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; - if (!block->valid) - valid_block = 0; -#endif - } - } -#ifdef USE_NEW_DYNAREC - if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { - block->flags &= ~CODEBLOCK_WAS_RECOMPILED; - if (block->flags & CODEBLOCK_BYTE_MASK) - block->flags |= CODEBLOCK_NO_IMMEDIATES; - else - block->flags |= CODEBLOCK_BYTE_MASK; - } - if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) -#else - if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) -#endif - { - /* FPU top-of-stack does not match the value this block was compiled - with, re-compile using dynamic top-of-stack*/ -#ifdef USE_NEW_DYNAREC - block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); -#else - block->flags &= ~CODEBLOCK_STATIC_TOP; - block->was_recompiled = 0; -#endif - } + if ((block->phys_2 ^ phys_addr_2) & ~0xfff) + valid_block = 0; + else if (block->page_mask2 & *block->dirty_mask2) { +# ifdef USE_NEW_DYNAREC + codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); + if (block->pc == BLOCK_PC_INVALID) + valid_block = 0; + else if (block->flags & CODEBLOCK_IN_DIRTY_LIST) + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; +# else + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; + if (!block->valid) + valid_block = 0; +# endif + } + } +# ifdef USE_NEW_DYNAREC + if (valid_block && (block->flags & CODEBLOCK_IN_DIRTY_LIST)) { + block->flags &= ~CODEBLOCK_WAS_RECOMPILED; + if (block->flags & CODEBLOCK_BYTE_MASK) + block->flags |= CODEBLOCK_NO_IMMEDIATES; + else + block->flags |= CODEBLOCK_BYTE_MASK; + } + if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED) && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != (cpu_state.TOP & 7)) +# else + if (valid_block && block->was_recompiled && (block->flags & CODEBLOCK_STATIC_TOP) && block->TOP != cpu_state.TOP) +# endif + { + /* FPU top-of-stack does not match the value this block was compiled + with, re-compile using dynamic top-of-stack*/ +# ifdef USE_NEW_DYNAREC + block->flags &= ~(CODEBLOCK_STATIC_TOP | CODEBLOCK_WAS_RECOMPILED); +# else + block->flags &= ~CODEBLOCK_STATIC_TOP; + block->was_recompiled = 0; +# endif + } } -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC if (valid_block && (block->flags & CODEBLOCK_WAS_RECOMPILED)) -#else +# else if (valid_block && block->was_recompiled) -#endif +# endif { - void (*code)(void) = (void *)&block->data[BLOCK_START]; + void (*code)(void) = (void *) &block->data[BLOCK_START]; -#ifndef USE_NEW_DYNAREC - codeblock_hash[hash] = block; -#endif - inrecomp = 1; - code(); -#ifdef USE_ACYCS - acycs = 0; -#endif - inrecomp = 0; +# ifndef USE_NEW_DYNAREC + codeblock_hash[hash] = block; +# endif + inrecomp = 1; + code(); +# ifdef USE_ACYCS + acycs = 0; +# endif + inrecomp = 0; -#ifndef USE_NEW_DYNAREC - if (!use32) cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif } else if (valid_block && !cpu_state.abrt) { -#ifdef USE_NEW_DYNAREC - start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; -#else - start_pc = cpu_state.pc; -#endif +# ifdef USE_NEW_DYNAREC + start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +# else + start_pc = cpu_state.pc; +# endif - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; -#if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(0); -#endif - codegen_block_start_recompile(block); - codegen_in_recompile = 1; +# if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(0); +# endif + codegen_block_start_recompile(block); + codegen_in_recompile = 1; - while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + while (!cpu_block_end) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif + fetchdat = fastreadl(cs + cpu_state.pc); +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - cpu_state.pc++; + cpu_state.pc++; - codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); + codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc - 1); - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - /* Cap source code at 4000 bytes per block; this - will prevent any block from spanning more than - 2 pages. In practice this limit will never be - hit, as host block size is only 2kB*/ -#ifdef USE_NEW_DYNAREC - if (((cs + cpu_state.pc) - start_pc) >= max_block_size) -#else - if ((cpu_state.pc - start_pc) > 1000) -#endif - CPU_BLOCK_END(); + /* Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB*/ +# ifdef USE_NEW_DYNAREC + if (((cs + cpu_state.pc) - start_pc) >= max_block_size) +# else + if ((cpu_state.pc - start_pc) > 1000) +# endif + CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end_recompile(block); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end_recompile(block); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); - codegen_in_recompile = 0; -#if defined(__APPLE__) && defined(__aarch64__) - pthread_jit_write_protect_np(1); -#endif + codegen_in_recompile = 0; +# if defined(__APPLE__) && defined(__aarch64__) + pthread_jit_write_protect_np(1); +# endif } else if (!cpu_state.abrt) { - /* Mark block but do not recompile */ -#ifdef USE_NEW_DYNAREC - start_pc = cs + cpu_state.pc; - const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; -#else - start_pc = cpu_state.pc; -#endif + /* Mark block but do not recompile */ +# ifdef USE_NEW_DYNAREC + start_pc = cs + cpu_state.pc; + const int max_block_size = (block->flags & CODEBLOCK_BYTE_MASK) ? ((128 - 25) - (start_pc & 0x3f)) : 1000; +# else + start_pc = cpu_state.pc; +# endif - cpu_block_end = 0; - x86_was_reset = 0; + cpu_block_end = 0; + x86_was_reset = 0; - codegen_block_init(phys_addr); + codegen_block_init(phys_addr); - while (!cpu_block_end) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - oldcpl = CPL; -#endif - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; + while (!cpu_block_end) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + oldcpl = CPL; +# endif + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; - cpu_state.ea_seg = &cpu_state.seg_ds; - cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + cpu_state.ssegs = 0; - codegen_endpc = (cs + cpu_state.pc) + 8; - fetchdat = fastreadl(cs + cpu_state.pc); + codegen_endpc = (cs + cpu_state.pc) + 8; + fetchdat = fastreadl(cs + cpu_state.pc); -#ifdef ENABLE_386_DYNAREC_LOG - if (in_smm) - x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); -#endif +# ifdef ENABLE_386_DYNAREC_LOG + if (in_smm) + x386_dynarec_log("[%04X:%08X] fetchdat = %08X\n", CS, cpu_state.pc, fetchdat); +# endif - if (!cpu_state.abrt) { - opcode = fetchdat & 0xFF; - fetchdat >>= 8; + if (!cpu_state.abrt) { + opcode = fetchdat & 0xFF; + fetchdat >>= 8; - cpu_state.pc++; + cpu_state.pc++; - x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); + x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); - if (x86_was_reset) - break; - } + if (x86_was_reset) + break; + } -#ifndef USE_NEW_DYNAREC - if (!use32) - cpu_state.pc &= 0xffff; -#endif +# ifndef USE_NEW_DYNAREC + if (!use32) + cpu_state.pc &= 0xffff; +# endif - /* Cap source code at 4000 bytes per block; this - will prevent any block from spanning more than - 2 pages. In practice this limit will never be - hit, as host block size is only 2kB */ -#ifdef USE_NEW_DYNAREC - if (((cs + cpu_state.pc) - start_pc) >= max_block_size) -#else - if ((cpu_state.pc - start_pc) > 1000) -#endif - CPU_BLOCK_END(); + /* Cap source code at 4000 bytes per block; this + will prevent any block from spanning more than + 2 pages. In practice this limit will never be + hit, as host block size is only 2kB */ +# ifdef USE_NEW_DYNAREC + if (((cs + cpu_state.pc) - start_pc) >= max_block_size) +# else + if ((cpu_state.pc - start_pc) > 1000) +# endif + CPU_BLOCK_END(); - if (cpu_state.flags & T_FLAG) - CPU_BLOCK_END(); - if (smi_line) - CPU_BLOCK_END(); - if (nmi && nmi_enable && nmi_mask) - CPU_BLOCK_END(); - if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) - CPU_BLOCK_END(); + if (cpu_state.flags & T_FLAG) + CPU_BLOCK_END(); + if (smi_line) + CPU_BLOCK_END(); + if (nmi && nmi_enable && nmi_mask) + CPU_BLOCK_END(); + if ((cpu_state.flags & I_FLAG) && pic.int_pending && !cpu_end_block_after_ins) + CPU_BLOCK_END(); - if (cpu_end_block_after_ins) { - cpu_end_block_after_ins--; - if (!cpu_end_block_after_ins) - CPU_BLOCK_END(); - } + if (cpu_end_block_after_ins) { + cpu_end_block_after_ins--; + if (!cpu_end_block_after_ins) + CPU_BLOCK_END(); + } - if (cpu_state.abrt) { - if (!(cpu_state.abrt & ABRT_EXPECTED)) - codegen_block_remove(); - CPU_BLOCK_END(); - } - } + if (cpu_state.abrt) { + if (!(cpu_state.abrt & ABRT_EXPECTED)) + codegen_block_remove(); + CPU_BLOCK_END(); + } + } - cpu_end_block_after_ins = 0; + cpu_end_block_after_ins = 0; - if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) - codegen_block_end(); + if ((!cpu_state.abrt || (cpu_state.abrt & ABRT_EXPECTED)) && !x86_was_reset) + codegen_block_end(); - if (x86_was_reset) - codegen_reset(); + if (x86_was_reset) + codegen_reset(); } -#ifdef USE_NEW_DYNAREC +# ifdef USE_NEW_DYNAREC else - cpu_state.oldpc = cpu_state.pc; -#endif + cpu_state.oldpc = cpu_state.pc; +# endif } - void exec386_dynarec(int cycs) { - int vector, tempi; - int cycdiff; - int oldcyc, oldcyc2; + int vector, tempi; + int cycdiff; + int oldcyc, oldcyc2; uint64_t oldtsc, delta; int cyc_period = cycs / 2000; /*5us*/ -#ifdef USE_ACYCS +# ifdef USE_ACYCS acycs = 0; -#endif +# endif cycles_main += cycs; while (cycles_main > 0) { - int cycles_start; + int cycles_start; - cycles += cyc_period; - cycles_start = cycles; + cycles += cyc_period; + cycles_start = cycles; - while (cycles > 0) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; - cpu_state.oldpc = cpu_state.pc; - oldcpl = CPL; - cpu_state.op32 = use32; + while (cycles > 0) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; + cpu_state.oldpc = cpu_state.pc; + oldcpl = CPL; + cpu_state.op32 = use32; - cycdiff = 0; -#endif - oldcyc = oldcyc2 = cycles; - cycles_old = cycles; - oldtsc = tsc; - tsc_old = tsc; - if (!CACHE_ON()) /*Interpret block*/ - { - exec386_dynarec_int(); - } - else - { - exec386_dynarec_dyn(); - } + cycdiff = 0; +# endif + oldcyc = oldcyc2 = cycles; + cycles_old = cycles; + oldtsc = tsc; + tsc_old = tsc; + if (!CACHE_ON()) /*Interpret block*/ + { + exec386_dynarec_int(); + } else { + exec386_dynarec_dyn(); + } - if (cpu_state.abrt) { - flags_rebuild(); - tempi = cpu_state.abrt & ABRT_MASK; - cpu_state.abrt = 0; - x86_doabrt(tempi); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - cpu_state.pc = cpu_state.oldpc; -#ifndef USE_NEW_DYNAREC - CS = oldcs; -#endif - pmodeint(8, 0); - if (cpu_state.abrt) { - cpu_state.abrt = 0; - softresetx86(); - cpu_set_edx(); -#ifdef ENABLE_386_DYNAREC_LOG - x386_dynarec_log("Triple fault - reset\n"); -#endif - } - } - } + if (cpu_state.abrt) { + flags_rebuild(); + tempi = cpu_state.abrt & ABRT_MASK; + cpu_state.abrt = 0; + x86_doabrt(tempi); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + cpu_state.pc = cpu_state.oldpc; +# ifndef USE_NEW_DYNAREC + CS = oldcs; +# endif + pmodeint(8, 0); + if (cpu_state.abrt) { + cpu_state.abrt = 0; + softresetx86(); + cpu_set_edx(); +# ifdef ENABLE_386_DYNAREC_LOG + x386_dynarec_log("Triple fault - reset\n"); +# endif + } + } + } - if (smi_line) - enter_smm_check(0); - else if (nmi && nmi_enable && nmi_mask) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - x86_int(2); - nmi_enable = 0; -#ifdef OLD_NMI_BEHAVIOR - if (nmi_auto_clear) { - nmi_auto_clear = 0; - nmi = 0; - } -#else - nmi = 0; -#endif - } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { - vector = picinterrupt(); - if (vector != -1) { -#ifndef USE_NEW_DYNAREC - oldcs = CS; -#endif - cpu_state.oldpc = cpu_state.pc; - x86_int(vector); - } - } + if (smi_line) + enter_smm_check(0); + else if (nmi && nmi_enable && nmi_mask) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + x86_int(2); + nmi_enable = 0; +# ifdef OLD_NMI_BEHAVIOR + if (nmi_auto_clear) { + nmi_auto_clear = 0; + nmi = 0; + } +# else + nmi = 0; +# endif + } else if ((cpu_state.flags & I_FLAG) && pic.int_pending) { + vector = picinterrupt(); + if (vector != -1) { +# ifndef USE_NEW_DYNAREC + oldcs = CS; +# endif + cpu_state.oldpc = cpu_state.pc; + x86_int(vector); + } + } - cycdiff = oldcyc - cycles; - delta = tsc - oldtsc; - if (delta > 0) { - /* TSC has changed, this means interim timer processing has happened, - see how much we still need to add. */ - cycdiff -= delta; - if (cycdiff > 0) - tsc += cycdiff; - } else { - /* TSC has not changed. */ - tsc += cycdiff; - } + cycdiff = oldcyc - cycles; + delta = tsc - oldtsc; + if (delta > 0) { + /* TSC has changed, this means interim timer processing has happened, + see how much we still need to add. */ + cycdiff -= delta; + if (cycdiff > 0) + tsc += cycdiff; + } else { + /* TSC has not changed. */ + tsc += cycdiff; + } - if (cycdiff > 0) { - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) - timer_process_inline(); - } + if (cycdiff > 0) { + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) + timer_process_inline(); + } -#ifdef USE_GDBSTUB - if (gdbstub_instruction()) - return; -#endif - } +# ifdef USE_GDBSTUB + if (gdbstub_instruction()) + return; +# endif + } - cycles_main -= (cycles_start - cycles); + cycles_main -= (cycles_start - cycles); } } #endif diff --git a/src/cpu/386_dynarec_ops.c b/src/cpu/386_dynarec_ops.c index 0b02676f8..f3e2f6e6e 100644 --- a/src/cpu/386_dynarec_ops.c +++ b/src/cpu/386_dynarec_ops.c @@ -5,7 +5,7 @@ #include #include #ifndef INFINITY -# define INFINITY (__builtin_inff()) +# define INFINITY (__builtin_inff()) #endif #include <86box/86box.h> @@ -25,57 +25,61 @@ #define CPU_BLOCK_END() cpu_block_end = 1 #ifndef IS_DYNAREC -#define IS_DYNAREC +# define IS_DYNAREC #endif #include "386_common.h" - -static __inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void +fetch_ea_32_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -static __inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void +fetch_ea_16_long(uint32_t rmdat) { - eal_r = eal_w = NULL; - easeg = cpu_state.ea_seg->base; - if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) - { - uint32_t addr = easeg + cpu_state.eaaddr; - if ( readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_r = (uint32_t *)(readlookup2[addr >> 12] + addr); - if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) - eal_w = (uint32_t *)(writelookup2[addr >> 12] + addr); - } + eal_r = eal_w = NULL; + easeg = cpu_state.ea_seg->base; + if (easeg != 0xFFFFFFFF && ((easeg + cpu_state.eaaddr) & 0xFFF) <= 0xFFC) { + uint32_t addr = easeg + cpu_state.eaaddr; + if (readlookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_r = (uint32_t *) (readlookup2[addr >> 12] + addr); + if (writelookup2[addr >> 12] != (uintptr_t) LOOKUP_INV) + eal_w = (uint32_t *) (writelookup2[addr >> 12] + addr); + } } -#define fetch_ea_16(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_16_long(rmdat); -#define fetch_ea_32(rmdat) cpu_state.pc++; if (cpu_mod != 3) fetch_ea_32_long(rmdat); - +#define fetch_ea_16(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_16_long(rmdat); +#define fetch_ea_32(rmdat) \ + cpu_state.pc++; \ + if (cpu_mod != 3) \ + fetch_ea_32_long(rmdat); #define PREFETCH_RUN(instr_cycles, bytes, modrm, reads, read_ls, writes, write_ls, ea32) #define PREFETCH_PREFIX() #define PREFETCH_FLUSH() -#define OP_TABLE(name) dynarec_ops_ ## name +#define OP_TABLE(name) dynarec_ops_##name #define CLOCK_CYCLES(c) #if 0 -#define CLOCK_CYCLES_FPU(c) -#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) +# define CLOCK_CYCLES_FPU(c) +# define CONCURRENCY_CYCLES(c) fpu_cycles = (c) #else -#define CLOCK_CYCLES_FPU(c) -#define CONCURRENCY_CYCLES(c) +# define CLOCK_CYCLES_FPU(c) +# define CONCURRENCY_CYCLES(c) #endif #define CLOCK_CYCLES_ALWAYS(c) cycles -= (c) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index d5f62f74f..cad5a7b05 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -40,128 +40,137 @@ */ #include "x86_ops.h" +#define ILLEGAL_ON(cond) \ + do { \ + if ((cond)) { \ + cpu_state.pc = cpu_state.oldpc; \ + x86illegal(); \ + return 0; \ + } \ + } while (0) -#define ILLEGAL_ON(cond) \ - do \ - { \ - if ((cond)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 0; \ - } \ - } while (0) - -static __inline void PUSH_W(uint16_t val) +static __inline void +PUSH_W(uint16_t val) { - if (stack32) - { - writememw(ss, ESP - 2, val); if (cpu_state.abrt) return; - ESP -= 2; - } - else - { - writememw(ss, (SP - 2) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, val); + if (cpu_state.abrt) + return; + ESP -= 2; + } else { + writememw(ss, (SP - 2) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 2; + } } -static __inline void PUSH_L(uint32_t val) +static __inline void +PUSH_L(uint32_t val) { - if (stack32) - { - writememl(ss, ESP - 4, val); if (cpu_state.abrt) return; - ESP -= 4; - } - else - { - writememl(ss, (SP - 4) & 0xFFFF, val); if (cpu_state.abrt) return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, val); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, (SP - 4) & 0xFFFF, val); + if (cpu_state.abrt) + return; + SP -= 4; + } } -static __inline uint16_t POP_W(void) +static __inline uint16_t +POP_W(void) { - uint16_t ret; - if (stack32) - { - ret = readmemw(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - } - else - { - ret = readmemw(ss, SP); if (cpu_state.abrt) return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + return ret; } -static __inline uint32_t POP_L(void) +static __inline uint32_t +POP_L(void) { - uint32_t ret; - if (stack32) - { - ret = readmeml(ss, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - } - else - { - ret = readmeml(ss, SP); if (cpu_state.abrt) return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } -static __inline uint16_t POP_W_seg(uint32_t seg) +static __inline uint16_t +POP_W_seg(uint32_t seg) { - uint16_t ret; - if (stack32) - { - ret = readmemw(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 2; - } - else - { - ret = readmemw(seg, SP); if (cpu_state.abrt) return 0; - SP += 2; - } - return ret; + uint16_t ret; + if (stack32) { + ret = readmemw(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; + } else { + ret = readmemw(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 2; + } + return ret; } -static __inline uint32_t POP_L_seg(uint32_t seg) +static __inline uint32_t +POP_L_seg(uint32_t seg) { - uint32_t ret; - if (stack32) - { - ret = readmeml(seg, ESP); if (cpu_state.abrt) return 0; - ESP += 4; - } - else - { - ret = readmeml(seg, SP); if (cpu_state.abrt) return 0; - SP += 4; - } - return ret; + uint32_t ret; + if (stack32) { + ret = readmeml(seg, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + ret = readmeml(seg, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } + return ret; } static int fopcode; -static int ILLEGAL(uint32_t fetchdat) +static int +ILLEGAL(uint32_t fetchdat) { - pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); - cpu_state.pc = cpu_state.oldpc; + pclog("[%04X:%08X] Illegal instruction %08X (%02X)\n", CS, cpu_state.pc, fetchdat, fopcode); + cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; + x86illegal(); + return 0; } - #ifdef ENABLE_386_DYNAREC_LOG -extern void x386_dynarec_log(const char *fmt, ...); +extern void x386_dynarec_log(const char *fmt, ...); #else -#ifndef x386_dynarec_log -#define x386_dynarec_log(fmt, ...) -#endif +# ifndef x386_dynarec_log +# define x386_dynarec_log(fmt, ...) +# endif #endif #include "x86seg.h" @@ -196,9 +205,9 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_pmode.h" #include "x86_ops_prefix.h" #ifdef IS_DYNAREC -#include "x86_ops_rep_dyn.h" +# include "x86_ops_rep_dyn.h" #else -#include "x86_ops_rep.h" +# include "x86_ops_rep.h" #endif #include "x86_ops_ret.h" #include "x86_ops_set.h" @@ -211,157 +220,160 @@ extern void x386_dynarec_log(const char *fmt, ...); #include "x86_ops_3dnow.h" #include - -static int opVPCEXT(uint32_t fetchdat) +static int +opVPCEXT(uint32_t fetchdat) { - uint8_t b1, b2; - uint16_t cent; - time_t now; - struct tm *tm; + uint8_t b1, b2; + uint16_t cent; + time_t now; + struct tm *tm; - if (!is_vpc) /* only emulate this on Virtual PC machines */ - return ILLEGAL(fetchdat); + if (!is_vpc) /* only emulate this on Virtual PC machines */ + return ILLEGAL(fetchdat); - cpu_state.pc += 2; + cpu_state.pc += 2; - b1 = fetchdat & 0xff; - b2 = (fetchdat >> 8) & 0xff; + b1 = fetchdat & 0xff; + b2 = (fetchdat >> 8) & 0xff; - /* a lot of these opcodes (which?) return illegal instruction in user mode */ - ILLEGAL_ON(CPL > 0); + /* a lot of these opcodes (which?) return illegal instruction in user mode */ + ILLEGAL_ON(CPL > 0); - CLOCK_CYCLES(1); + CLOCK_CYCLES(1); - /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ - if (b1 == 0x03) { - (void)time(&now); - tm = localtime(&now); - } + /* 0f 3f 03 xx opcodes are mostly related to the host clock, so fetch it now */ + if (b1 == 0x03) { + (void) time(&now); + tm = localtime(&now); + } - if ((b1 == 0x07) && (b2 == 0x0b)) { - /* 0f 3f 07 0b: unknown, EDX output depends on EAX input */ - switch (EAX) { - case 0x00000000: - EDX = 0x00000003; - break; + if ((b1 == 0x07) && (b2 == 0x0b)) { + /* 0f 3f 07 0b: unknown, EDX output depends on EAX input */ + switch (EAX) { + case 0x00000000: + EDX = 0x00000003; + break; - case 0x00000001: - EDX = 0x00000012; - break; + case 0x00000001: + EDX = 0x00000012; + break; - case 0x00000002: - case 0x00000003: - case 0x00000004: - case 0x00000005: - EDX = 0x00000001; - break; + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + EDX = 0x00000001; + break; - case 0x00000007: - EDX = 0x0000009c; - break; + case 0x00000007: + EDX = 0x0000009c; + break; - default: - EDX = 0x00000000; - if (EAX > 0x00000012) /* unknown EAX values set zero flag */ - cpu_state.flags &= ~(Z_FLAG); - } - } else if ((b1 == 0x03) && (b2 == 0x00)) { - /* 0f 3f 03 00: host time in BCD */ - EDX = BCD8(tm->tm_hour); - ECX = BCD8(tm->tm_min); - EAX = BCD8(tm->tm_sec); - } else if ((b1 == 0x03) && (b2 == 0x01)) { - /* 0f 3f 03 00: host date in BCD */ - EDX = BCD8(tm->tm_year % 100); - ECX = BCD8(tm->tm_mon + 1); - EAX = BCD8(tm->tm_mday); - cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */ - EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); - } else if ((b1 == 0x03) && (b2 == 0x03)) { - /* 0f 3f 03 03: host time in binary */ - EDX = tm->tm_hour; - ECX = tm->tm_min; - EAX = tm->tm_sec; - } else if ((b1 == 0x03) && (b2 == 0x04)) { - /* 0f 3f 03 04: host date in binary */ - EDX = 1900 + tm->tm_year; - ECX = tm->tm_mon + 1; - EBX = tm->tm_mday; - } else if ((b1 == 0x03) && (b2 == 0x05)) { - /* 0f 3f 03 05: unknown */ - EBX = 0x0000000F; - ECX = 0x0000000A; - } else if ((b1 == 0x03) && (b2 == 0x06)) { - /* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */ - EBX = 0x00000000; - ECX = 0x00000000; - } else if ((b1 == 0x03) && (b2 >= 0x07)) { - /* 0f 3f 03 07+: set zero flag */ - cpu_state.flags &= ~(Z_FLAG); - } else if ((b1 == 0x0a) && (b2 == 0x00)) { - /* 0f 3f 0a 00: memory size in KB */ - EAX = mem_size; - } else if ((b1 == 0x11) && (b2 == 0x00)) { - /* 0f 3f 11 00: unknown, set EAX to 0 */ - EAX = 0x00000000; - } else if ((b1 == 0x11) && (b2 == 0x01)) { - /* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */ - EAX = 0x00000000; - cpu_state.flags &= ~(Z_FLAG); - } else if ((b1 == 0x11) && (b2 == 0x02)) { - /* 0f 3f 11 02: unknown, no-op */ - } else { - /* other unknown opcodes: illegal instruction */ - cpu_state.pc = cpu_state.oldpc; + default: + EDX = 0x00000000; + if (EAX > 0x00000012) /* unknown EAX values set zero flag */ + cpu_state.flags &= ~(Z_FLAG); + } + } else if ((b1 == 0x03) && (b2 == 0x00)) { + /* 0f 3f 03 00: host time in BCD */ + EDX = BCD8(tm->tm_hour); + ECX = BCD8(tm->tm_min); + EAX = BCD8(tm->tm_sec); + } else if ((b1 == 0x03) && (b2 == 0x01)) { + /* 0f 3f 03 00: host date in BCD */ + EDX = BCD8(tm->tm_year % 100); + ECX = BCD8(tm->tm_mon + 1); + EAX = BCD8(tm->tm_mday); + cent = (((tm->tm_year - (tm->tm_year % 100)) / 100) % 4); /* Sunday = 0 */ + EBX = ((tm->tm_mday + tm->tm_mon + (tm->tm_year % 100) + cent + 3) % 7); + } else if ((b1 == 0x03) && (b2 == 0x03)) { + /* 0f 3f 03 03: host time in binary */ + EDX = tm->tm_hour; + ECX = tm->tm_min; + EAX = tm->tm_sec; + } else if ((b1 == 0x03) && (b2 == 0x04)) { + /* 0f 3f 03 04: host date in binary */ + EDX = 1900 + tm->tm_year; + ECX = tm->tm_mon + 1; + EBX = tm->tm_mday; + } else if ((b1 == 0x03) && (b2 == 0x05)) { + /* 0f 3f 03 05: unknown */ + EBX = 0x0000000F; + ECX = 0x0000000A; + } else if ((b1 == 0x03) && (b2 == 0x06)) { + /* 0f 3f 03 06: some kind of timestamp. BX jumps around very quickly, CX not so much. */ + EBX = 0x00000000; + ECX = 0x00000000; + } else if ((b1 == 0x03) && (b2 >= 0x07)) { + /* 0f 3f 03 07+: set zero flag */ + cpu_state.flags &= ~(Z_FLAG); + } else if ((b1 == 0x0a) && (b2 == 0x00)) { + /* 0f 3f 0a 00: memory size in KB */ + EAX = mem_size; + } else if ((b1 == 0x11) && (b2 == 0x00)) { + /* 0f 3f 11 00: unknown, set EAX to 0 */ + EAX = 0x00000000; + } else if ((b1 == 0x11) && (b2 == 0x01)) { + /* 0f 3f 11 00: unknown, set EAX to 0 and set zero flag */ + EAX = 0x00000000; + cpu_state.flags &= ~(Z_FLAG); + } else if ((b1 == 0x11) && (b2 == 0x02)) { + /* 0f 3f 11 02: unknown, no-op */ + } else { + /* other unknown opcodes: illegal instruction */ + cpu_state.pc = cpu_state.oldpc; - pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2); - x86illegal(); - return 0; - } + pclog("Illegal VPCEXT %08X (%02X %02X)\n", fetchdat, b1, b2); + x86illegal(); + return 0; + } - return 1; + return 1; } - -static int op0F_w_a16(uint32_t fetchdat) +static int +op0F_w_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode](fetchdat >> 8); + return x86_opcodes_0f[opcode](fetchdat >> 8); } -static int op0F_l_a16(uint32_t fetchdat) +static int +op0F_l_a16(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); } -static int op0F_w_a32(uint32_t fetchdat) +static int +op0F_w_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); } -static int op0F_l_a32(uint32_t fetchdat) +static int +op0F_l_a32(uint32_t fetchdat) { - int opcode = fetchdat & 0xff; - fopcode = opcode; - cpu_state.pc++; + int opcode = fetchdat & 0xff; + fopcode = opcode; + cpu_state.pc++; - PREFETCH_PREFIX(); + PREFETCH_PREFIX(); - return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); + return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } const OpFn OP_TABLE(186_0f)[1024] = diff --git a/src/cpu/8080.c b/src/cpu/8080.c index afea3625c..6f3dd4267 100644 --- a/src/cpu/8080.c +++ b/src/cpu/8080.c @@ -13,7 +13,6 @@ * Copyright 2022 Cacodemon345 */ - #include #include #include "cpu.h" @@ -38,15 +37,14 @@ clock_start(void) cycdiff = cycles; } - static void clock_end(void) { int diff = cycdiff - cycles; /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ - tsc += (uint64_t)diff * ((uint64_t)xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ - if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t)tsc)) + tsc += (uint64_t) diff * ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to the right and then multiply. */ + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint32_t) tsc)) timer_process(); } @@ -73,7 +71,7 @@ readmemb(uint32_t a) } static uint8_t -ins_fetch(i8080* cpu) +ins_fetch(i8080 *cpu) { uint8_t ret = cpu->readmembyte(cpu->pmembase + cpu->pc); @@ -83,22 +81,22 @@ ins_fetch(i8080* cpu) #endif void -transfer_from_808x(i8080* cpu) +transfer_from_808x(i8080 *cpu) { - cpu->hl = BX; - cpu->bc = CX; - cpu->de = DX; - cpu->a = AL; - cpu->flags = cpu_state.flags & 0xFF; - cpu->sp = BP; - cpu->pc = cpu_state.pc; - cpu->oldpc = cpu_state.oldpc; + cpu->hl = BX; + cpu->bc = CX; + cpu->de = DX; + cpu->a = AL; + cpu->flags = cpu_state.flags & 0xFF; + cpu->sp = BP; + cpu->pc = cpu_state.pc; + cpu->oldpc = cpu_state.oldpc; cpu->pmembase = cs; cpu->dmembase = ds; } void -transfer_to_808x(i8080* cpu) +transfer_to_808x(i8080 *cpu) { BX = cpu->hl; CX = cpu->bc; @@ -106,7 +104,7 @@ transfer_to_808x(i8080* cpu) AL = cpu->a; cpu_state.flags &= 0xFF00; cpu_state.flags |= cpu->flags & 0xFF; - BP = cpu->sp; + BP = cpu->sp; cpu_state.pc = cpu->pc; } @@ -114,16 +112,31 @@ uint8_t getreg_i8080(i8080 *cpu, uint8_t reg) { uint8_t ret = 0xFF; - switch(reg) - { - case 0x0: ret = cpu->b; break; - case 0x1: ret = cpu->c; break; - case 0x2: ret = cpu->d; break; - case 0x3: ret = cpu->e; break; - case 0x4: ret = cpu->h; break; - case 0x5: ret = cpu->l; break; - case 0x6: ret = cpu->readmembyte(cpu->dmembase + cpu->sp); break; - case 0x7: ret = cpu->a; break; + switch (reg) { + case 0x0: + ret = cpu->b; + break; + case 0x1: + ret = cpu->c; + break; + case 0x2: + ret = cpu->d; + break; + case 0x3: + ret = cpu->e; + break; + case 0x4: + ret = cpu->h; + break; + case 0x5: + ret = cpu->l; + break; + case 0x6: + ret = cpu->readmembyte(cpu->dmembase + cpu->sp); + break; + case 0x7: + ret = cpu->a; + break; } return ret; } @@ -132,16 +145,31 @@ uint8_t getreg_i8080_emu(i8080 *cpu, uint8_t reg) { uint8_t ret = 0xFF; - switch(reg) - { - case 0x0: ret = CH; break; - case 0x1: ret = CL; break; - case 0x2: ret = DH; break; - case 0x3: ret = DL; break; - case 0x4: ret = BH; break; - case 0x5: ret = BL; break; - case 0x6: ret = cpu->readmembyte(cpu->dmembase + BP); break; - case 0x7: ret = AL; break; + switch (reg) { + case 0x0: + ret = CH; + break; + case 0x1: + ret = CL; + break; + case 0x2: + ret = DH; + break; + case 0x3: + ret = DL; + break; + case 0x4: + ret = BH; + break; + case 0x5: + ret = BL; + break; + case 0x6: + ret = cpu->readmembyte(cpu->dmembase + BP); + break; + case 0x7: + ret = AL; + break; } return ret; } @@ -149,57 +177,87 @@ getreg_i8080_emu(i8080 *cpu, uint8_t reg) void setreg_i8080_emu(i8080 *cpu, uint8_t reg, uint8_t val) { - switch(reg) - { - case 0x0: CH = val; break; - case 0x1: CL = val; break; - case 0x2: DH = val; break; - case 0x3: DL = val; break; - case 0x4: BH = val; break; - case 0x5: BL = val; break; - case 0x6: cpu->writemembyte(cpu->dmembase + BP, val); break; - case 0x7: AL = val; break; + switch (reg) { + case 0x0: + CH = val; + break; + case 0x1: + CL = val; + break; + case 0x2: + DH = val; + break; + case 0x3: + DL = val; + break; + case 0x4: + BH = val; + break; + case 0x5: + BL = val; + break; + case 0x6: + cpu->writemembyte(cpu->dmembase + BP, val); + break; + case 0x7: + AL = val; + break; } } void setreg_i8080(i8080 *cpu, uint8_t reg, uint8_t val) { - switch(reg) - { - case 0x0: cpu->b = val; break; - case 0x1: cpu->c = val; break; - case 0x2: cpu->d = val; break; - case 0x3: cpu->e = val; break; - case 0x4: cpu->h = val; break; - case 0x5: cpu->l = val; break; - case 0x6: cpu->writemembyte(cpu->dmembase + cpu->sp, val); break; - case 0x7: cpu->a = val; break; + switch (reg) { + case 0x0: + cpu->b = val; + break; + case 0x1: + cpu->c = val; + break; + case 0x2: + cpu->d = val; + break; + case 0x3: + cpu->e = val; + break; + case 0x4: + cpu->h = val; + break; + case 0x5: + cpu->l = val; + break; + case 0x6: + cpu->writemembyte(cpu->dmembase + cpu->sp, val); + break; + case 0x7: + cpu->a = val; + break; } } void -interpret_exec8080(i8080* cpu, uint8_t opcode) +interpret_exec8080(i8080 *cpu, uint8_t opcode) { switch (opcode) { case 0x00: - { - break; - } + { + break; + } } } /* Actually implement i8080 emulation. */ void -exec8080(i8080* cpu, int cycs) +exec8080(i8080 *cpu, int cycs) { #ifdef UNUSED_8080_VARS - uint8_t temp = 0, temp2; - uint8_t old_af; - uint8_t handled = 0; + uint8_t temp = 0, temp2; + uint8_t old_af; + uint8_t handled = 0; uint16_t addr, tempw; uint16_t new_ip; - int bits; + int bits; #endif cycles += cycs; @@ -209,17 +267,18 @@ exec8080(i8080* cpu, int cycs) if (!repeating) { cpu->oldpc = cpu->pc; - opcode = cpu->fetchinstruction(cpu); - oldc = cpu->flags & C_FLAG_I8080; + opcode = cpu->fetchinstruction(cpu); + oldc = cpu->flags & C_FLAG_I8080; i8080_wait(1, 0); } completed = 1; if (completed) { - repeating = 0; - in_rep = 0; + repeating = 0; + in_rep = 0; rep_c_flag = 0; cpu->endclock(); - if (cpu->checkinterrupts) cpu->checkinterrupts(); + if (cpu->checkinterrupts) + cpu->checkinterrupts(); } } } diff --git a/src/cpu/808x.c b/src/cpu/808x.c index cc8cbc903..b2859153a 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -1085,9 +1085,9 @@ rep_action(int bits) access(71, bits); pfq_clear(); if (is_nec && (ovr_seg != NULL)) - set_ip(cpu_state.pc - 3); + set_ip(cpu_state.pc - 3); else - set_ip(cpu_state.pc - 2); + set_ip(cpu_state.pc - 2); t = 0; } if (t == 0) { @@ -1683,7 +1683,7 @@ execx86(int cycs) // pclog("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); if (is186) { switch (opcode) { - case 0x60: /*PUSHA/PUSH R*/ + case 0x60: /*PUSHA/PUSH R*/ orig_sp = SP; wait(1, 0); push(&AX); @@ -1696,12 +1696,12 @@ execx86(int cycs) push(&DI); handled = 1; break; - case 0x61: /*POPA/POP R*/ + case 0x61: /*POPA/POP R*/ wait(9, 0); - DI = pop(); - SI = pop(); - BP = pop(); - (void) pop(); /* former orig_sp */ + DI = pop(); + SI = pop(); + BP = pop(); + (void) pop(); /* former orig_sp */ BX = pop(); DX = pop(); CX = pop(); @@ -1710,9 +1710,9 @@ execx86(int cycs) break; case 0x62: /* BOUND r/m */ - lowbound = 0; + lowbound = 0; highbound = 0; - regval = 0; + regval = 0; do_mod_rm(); lowbound = readmemw(easeg, cpu_state.eaaddr); @@ -1733,7 +1733,7 @@ execx86(int cycs) in_rep = (opcode == 0x64 ? 1 : 2); rep_c_flag = 1; completed = 0; - handled = 1; + handled = 1; } break; @@ -1746,7 +1746,7 @@ execx86(int cycs) case 0x69: immediate = 0; - bits = 16; + bits = 16; do_mod_rm(); read_ea(0, 16); immediate = pfq_fetchw(); @@ -1764,7 +1764,7 @@ execx86(int cycs) case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */ immediate = 0; - bits = 16; + bits = 16; do_mod_rm(); read_ea(0, 16); immediate = pfq_fetchb(); @@ -1805,13 +1805,13 @@ execx86(int cycs) case 0x6e: case 0x6f: /* OUTM DW, src/OUTS DX, src */ dest_seg = ovr_seg ? *ovr_seg : ds; - bits = 8 << (opcode & 1); - handled = 1; + bits = 8 << (opcode & 1); + handled = 1; if (!repeating) wait(2, 0); if (rep_action(bits)) - break; + break; else if (!repeating) wait(7, 0); @@ -1832,9 +1832,9 @@ execx86(int cycs) case 0xc8: /* ENTER/PREPARE */ tempw_int = 0; - size = pfq_fetchw(); - nests = pfq_fetchb(); - i = 0; + size = pfq_fetchw(); + nests = pfq_fetchb(); + i = 0; push(&BP); tempw_int = SP; @@ -1984,7 +1984,7 @@ execx86(int cycs) handled = 1; break; - case 0x2a: /* ROR4 r/m */ + case 0x2a: /* ROR4 r/m */ do_mod_rm(); wait(21, 0); @@ -2081,10 +2081,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2116,10 +2116,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2151,10 +2151,10 @@ execx86(int cycs) odd = !!(CL % 2); zero = 1; nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; wait(5, 0); for (i = 0; i < ((nibbles_count / 2) + odd); i++) { @@ -2206,7 +2206,7 @@ execx86(int cycs) } } setr8(cpu_rm, bit_offset); - + handled = 1; break; @@ -2501,9 +2501,9 @@ execx86(int cycs) wait(1, 0); break; - case 0x60: /*JO alias*/ - case 0x70: /*JO*/ - case 0x61: /*JNO alias*/ + case 0x60: /*JO alias*/ + case 0x70: /*JO*/ + case 0x61: /*JNO alias*/ case 0x71: /*JNO*/ jcc(opcode, cpu_state.flags & V_FLAG); break; @@ -2525,15 +2525,15 @@ execx86(int cycs) case 0x77: /*JNBE*/ jcc(opcode, cpu_state.flags & (C_FLAG | Z_FLAG)); break; - case 0x68: /*JS alias*/ - case 0x78: /*JS*/ - case 0x69: /*JNS alias*/ + case 0x68: /*JS alias*/ + case 0x78: /*JS*/ + case 0x69: /*JNS alias*/ case 0x79: /*JNS*/ jcc(opcode, cpu_state.flags & N_FLAG); break; - case 0x6A: /*JP alias*/ - case 0x7A: /*JP*/ - case 0x6B: /*JNP alias*/ + case 0x6A: /*JP alias*/ + case 0x7A: /*JP*/ + case 0x6B: /*JNP alias*/ case 0x7B: /*JNP*/ jcc(opcode, cpu_state.flags & P_FLAG); break; diff --git a/src/cpu/codegen_public.h b/src/cpu/codegen_public.h index fa7dad8a5..36393296e 100644 --- a/src/cpu/codegen_public.h +++ b/src/cpu/codegen_public.h @@ -36,29 +36,27 @@ #define _CODEGEN_PUBLIC_H_ #ifndef USE_NEW_DYNAREC -#define PAGE_MASK_INDEX_MASK 3 -#define PAGE_MASK_INDEX_SHIFT 10 -#define PAGE_MASK_SHIFT 4 +# define PAGE_MASK_INDEX_MASK 3 +# define PAGE_MASK_INDEX_SHIFT 10 +# define PAGE_MASK_SHIFT 4 #else -#define PAGE_MASK_SHIFT 6 +# define PAGE_MASK_SHIFT 6 #endif #define PAGE_MASK_MASK 63 #ifdef USE_NEW_DYNAREC -#define BLOCK_PC_INVALID 0xffffffff -#define BLOCK_INVALID 0 +# define BLOCK_PC_INVALID 0xffffffff +# define BLOCK_INVALID 0 #endif - -extern void codegen_init(void); +extern void codegen_init(void); #ifdef USE_NEW_DYNAREC -extern void codegen_close(void); +extern void codegen_close(void); #endif -extern void codegen_flush(void); - +extern void codegen_flush(void); /*Current physical page of block being recompiled. -1 if no recompilation taking place */ -extern uint32_t recomp_page; -extern int codegen_in_recompile; +extern uint32_t recomp_page; +extern int codegen_in_recompile; #endif diff --git a/src/cpu/codegen_timing_common.h b/src/cpu/codegen_timing_common.h index a3faca27d..679997802 100644 --- a/src/cpu/codegen_timing_common.h +++ b/src/cpu/codegen_timing_common.h @@ -3,11 +3,11 @@ /*Instruction has input dependency on register in REG field*/ #define SRCDEP_REG (1ull << 0) /*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1ull << 1) +#define SRCDEP_RM (1ull << 1) /*Instruction modifies register in REG field*/ #define DSTDEP_REG (1ull << 2) /*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1ull << 3) +#define DSTDEP_RM (1ull << 3) #define SRCDEP_SHIFT 4 #define DSTDEP_SHIFT 12 @@ -40,48 +40,45 @@ /*Instruction is MMX shift or pack/unpack instruction*/ #define MMX_SHIFTPACK (1ull << 22) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1ull << 23) +#define MMX_MULTIPLY (1ull << 23) /*Instruction pops the FPU stack*/ -#define FPU_POP (1ull << 24) +#define FPU_POP (1ull << 24) /*Instruction pops the FPU stack twice*/ -#define FPU_POP2 (1ull << 25) +#define FPU_POP2 (1ull << 25) /*Instruction pushes onto the FPU stack*/ -#define FPU_PUSH (1ull << 26) +#define FPU_PUSH (1ull << 26) /*Instruction writes to ST(0)*/ -#define FPU_WRITE_ST0 (1ull << 27) +#define FPU_WRITE_ST0 (1ull << 27) /*Instruction reads from ST(0)*/ -#define FPU_READ_ST0 (1ull << 28) +#define FPU_READ_ST0 (1ull << 28) /*Instruction reads from and writes to ST(0)*/ -#define FPU_RW_ST0 (3ull << 27) +#define FPU_RW_ST0 (3ull << 27) /*Instruction reads from ST(1)*/ -#define FPU_READ_ST1 (1ull << 29) +#define FPU_READ_ST1 (1ull << 29) /*Instruction writes to ST(1)*/ -#define FPU_WRITE_ST1 (1ull << 30) +#define FPU_WRITE_ST1 (1ull << 30) /*Instruction reads from and writes to ST(1)*/ -#define FPU_RW_ST1 (3ull << 29) +#define FPU_RW_ST1 (3ull << 29) /*Instruction reads from ST(reg)*/ -#define FPU_READ_STREG (1ull << 31) +#define FPU_READ_STREG (1ull << 31) /*Instruction writes to ST(reg)*/ #define FPU_WRITE_STREG (1ull << 32) /*Instruction reads from and writes to ST(reg)*/ -#define FPU_RW_STREG (3ull << 31) +#define FPU_RW_STREG (3ull << 31) -#define FPU_FXCH (1ull << 33) +#define FPU_FXCH (1ull << 33) +#define HAS_IMM8 (1ull << 34) +#define HAS_IMM1632 (1ull << 35) -#define HAS_IMM8 (1ull << 34) -#define HAS_IMM1632 (1ull << 35) - - -#define REGMASK_IMPL_ESP (1 << 8) +#define REGMASK_IMPL_ESP (1 << 8) #define REGMASK_SHIFTPACK (1 << 9) #define REGMASK_MULTIPLY (1 << 9) - extern uint64_t opcode_deps[256]; extern uint64_t opcode_deps_mod3[256]; extern uint64_t opcode_deps_0f[256]; @@ -119,114 +116,116 @@ extern uint64_t opcode_deps_81_mod3[8]; extern uint64_t opcode_deps_8x[8]; extern uint64_t opcode_deps_8x_mod3[8]; - - -static inline uint32_t get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) +static inline uint32_t +get_addr_regmask(uint64_t data, uint32_t fetchdat, int op_32) { - uint32_t addr_regmask = 0; + uint32_t addr_regmask = 0; - if (data & MODRM) - { - uint8_t modrm = fetchdat & 0xff; + if (data & MODRM) { + uint8_t modrm = fetchdat & 0xff; - if ((modrm & 0xc0) != 0xc0) - { - if (op_32 & 0x200) - { - if ((modrm & 0x7) == 4) - { - uint8_t sib = (fetchdat >> 8) & 0xff; + if ((modrm & 0xc0) != 0xc0) { + if (op_32 & 0x200) { + if ((modrm & 0x7) == 4) { + uint8_t sib = (fetchdat >> 8) & 0xff; - if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) - { - addr_regmask = 1 << (sib & 7); - if ((sib & 0x38) != 0x20) - addr_regmask |= 1 << ((sib >> 3) & 7); - } - } - else if ((modrm & 0xc7) != 5) - { - addr_regmask = 1 << (modrm & 7); - } - } - else - { - if ((modrm & 0xc7) != 0x06) - { - switch (modrm & 7) - { - case 0: addr_regmask = REG_BX | REG_SI; break; - case 1: addr_regmask = REG_BX | REG_DI; break; - case 2: addr_regmask = REG_BP | REG_SI; break; - case 3: addr_regmask = REG_BP | REG_DI; break; - case 4: addr_regmask = REG_SI; break; - case 5: addr_regmask = REG_DI; break; - case 6: addr_regmask = REG_BP; break; - case 7: addr_regmask = REG_BX; break; - } - } - } + if ((modrm & 0xc0) != 0xc0 && (sib & 7) != 5) { + addr_regmask = 1 << (sib & 7); + if ((sib & 0x38) != 0x20) + addr_regmask |= 1 << ((sib >> 3) & 7); + } + } else if ((modrm & 0xc7) != 5) { + addr_regmask = 1 << (modrm & 7); } + } else { + if ((modrm & 0xc7) != 0x06) { + switch (modrm & 7) { + case 0: + addr_regmask = REG_BX | REG_SI; + break; + case 1: + addr_regmask = REG_BX | REG_DI; + break; + case 2: + addr_regmask = REG_BP | REG_SI; + break; + case 3: + addr_regmask = REG_BP | REG_DI; + break; + case 4: + addr_regmask = REG_SI; + break; + case 5: + addr_regmask = REG_DI; + break; + case 6: + addr_regmask = REG_BP; + break; + case 7: + addr_regmask = REG_BX; + break; + } + } + } } + } - if (data & IMPL_ESP) - addr_regmask |= REGMASK_IMPL_ESP; + if (data & IMPL_ESP) + addr_regmask |= REGMASK_IMPL_ESP; - return addr_regmask; + return addr_regmask; } -static inline uint32_t get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) +static inline uint32_t +get_srcdep_mask(uint64_t data, uint32_t fetchdat, int bit8, int op_32) { - uint32_t mask = 0; - if (data & SRCDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & SRCDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> SRCDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; + uint32_t mask = 0; + if (data & SRCDEP_REG) { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & SRCDEP_RM) { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> SRCDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; - mask |= get_addr_regmask(data, fetchdat, op_32); + mask |= get_addr_regmask(data, fetchdat, op_32); - return mask; + return mask; } -static inline uint32_t get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) +static inline uint32_t +get_dstdep_mask(uint64_t data, uint32_t fetchdat, int bit8) { - uint32_t mask = 0; - if (data & DSTDEP_REG) - { - int reg = (fetchdat >> 3) & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - if (data & DSTDEP_RM) - { - int reg = fetchdat & 7; - if (bit8) - reg &= 3; - mask |= (1 << reg); - } - mask |= ((data >> DSTDEP_SHIFT) & 0xff); - if (data & MMX_SHIFTPACK) - mask |= REGMASK_SHIFTPACK; - if (data & MMX_MULTIPLY) - mask |= REGMASK_MULTIPLY; - if (data & IMPL_ESP) - mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); + uint32_t mask = 0; + if (data & DSTDEP_REG) { + int reg = (fetchdat >> 3) & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + if (data & DSTDEP_RM) { + int reg = fetchdat & 7; + if (bit8) + reg &= 3; + mask |= (1 << reg); + } + mask |= ((data >> DSTDEP_SHIFT) & 0xff); + if (data & MMX_SHIFTPACK) + mask |= REGMASK_SHIFTPACK; + if (data & MMX_MULTIPLY) + mask |= REGMASK_MULTIPLY; + if (data & IMPL_ESP) + mask |= REGMASK_IMPL_ESP | (1 << REG_ESP); - return mask; + return mask; } diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ea90814c9..58ddf8dc6 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1169,7 +1169,7 @@ cpu_set(void) #endif if ((cpu_s->cpu_type == CPU_K6_2P) || (cpu_s->cpu_type == CPU_K6_3P)) { - x86_opcodes_3DNOW = ops_3DNOWE; + x86_opcodes_3DNOW = ops_3DNOWE; x86_dynarec_opcodes_3DNOW = dynarec_ops_3DNOWE; } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 8ddf101c2..11e1bc93c 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -35,9 +35,9 @@ enum { enum { CPU_8088 = 1, /* 808x class CPUs */ CPU_8086, - CPU_V20, /* NEC 808x class CPUs */ + CPU_V20, /* NEC 808x class CPUs */ CPU_V30, - CPU_188, /* 18x class CPUs */ + CPU_188, /* 18x class CPUs */ CPU_186, CPU_286, /* 286 class CPUs */ CPU_386SX, /* 386 class CPUs */ diff --git a/src/cpu/fpu.c b/src/cpu/fpu.c index d41a58508..f75d07231 100644 --- a/src/cpu/fpu.c +++ b/src/cpu/fpu.c @@ -25,11 +25,9 @@ #include <86box/86box.h> #include "cpu.h" - #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; - void fpu_log(const char *fmt, ...) { @@ -42,17 +40,16 @@ fpu_log(const char *fmt, ...) } } #else -#define fpu_log(fmt, ...) +# define fpu_log(fmt, ...) #endif - int fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) { - const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int fpu_type = fpus[0].type; - int c = 0; + const CPU *cpu_s = &cpu_family->cpus[cpu]; + const FPU *fpus = cpu_s->fpus; + int fpu_type = fpus[0].type; + int c = 0; while (fpus[c].internal_name) { if (!strcmp(internal_name, fpus[c].internal_name)) @@ -63,13 +60,12 @@ fpu_get_type(const cpu_family_t *cpu_family, int cpu, const char *internal_name) return fpu_type; } - const char * fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; - int c = 0; + const FPU *fpus = cpu_s->fpus; + int c = 0; while (fpus[c].internal_name) { if (fpus[c].type == type) @@ -80,22 +76,20 @@ fpu_get_internal_name(const cpu_family_t *cpu_family, int cpu, int type) return fpus[0].internal_name; } - const char * fpu_get_name_from_index(const cpu_family_t *cpu_family, int cpu, int c) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + const FPU *fpus = cpu_s->fpus; return fpus[c].name; } - int fpu_get_type_from_index(const cpu_family_t *cpu_family, int cpu, int c) { const CPU *cpu_s = &cpu_family->cpus[cpu]; - const FPU *fpus = cpu_s->fpus; + const FPU *fpus = cpu_s->fpus; return fpus[c].type; } diff --git a/src/cpu/x86.c b/src/cpu/x86.c index df0c2244a..eb1dc463f 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -43,7 +43,7 @@ uint8_t opcode; /* The tables to speed up the setting of the Z, N, and P cpu_state.flags. */ -uint8_t znptable8[256]; +uint8_t znptable8[256]; uint16_t znptable16[65536]; /* A 16-bit zero, needed because some speed-up arrays contain pointers to it. */ @@ -52,7 +52,7 @@ uint16_t zero = 0; /* MOD and R/M stuff. */ uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; -uint32_t rmdat; +uint32_t rmdat; /* XT CPU multiplier. */ uint64_t xt_cpu_multi; @@ -72,13 +72,11 @@ uint32_t easeg; /* This is for the OPTI 283 special reset handling mode. */ int reset_on_hlt, hlt_reset_pending; - #ifdef ENABLE_X86_LOG -void dumpregs(int); +void dumpregs(int); int x86_do_log = ENABLE_X86_LOG; -int indump = 0; - +int indump = 0; static void x808x_log(const char *fmt, ...) @@ -86,60 +84,58 @@ x808x_log(const char *fmt, ...) va_list ap; if (x808x_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } - void dumpregs(int force) { - int c; + int c; char *seg_names[4] = { "ES", "CS", "SS", "DS" }; /* Only dump when needed, and only once.. */ if (indump || (!force && !dump_on_exit)) - return; + return; x808x_log("EIP=%08X CS=%04X DS=%04X ES=%04X SS=%04X FLAGS=%04X\n", - cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); + cpu_state.pc, CS, DS, ES, SS, cpu_state.flags); x808x_log("Old CS:EIP: %04X:%08X; %i ins\n", oldcs, cpu_state.oldpc, ins); for (c = 0; c < 4; c++) { - x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_names[c], _opseg[c]->base, _opseg[c]->limit, - _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); + x808x_log("%s : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_names[c], _opseg[c]->base, _opseg[c]->limit, + _opseg[c]->access, _opseg[c]->limit_low, _opseg[c]->limit_high); } if (is386) { - x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); - x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", - gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); - x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); - x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); - x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); - x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); - x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", - (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", - (use32) ? 32 : 16, (stack32) ? 32 : 16); - x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); - x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", - EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); + x808x_log("FS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + seg_fs, cpu_state.seg_fs.limit, cpu_state.seg_fs.access, cpu_state.seg_fs.limit_low, cpu_state.seg_fs.limit_high); + x808x_log("GS : base=%06X limit=%08X access=%02X limit_low=%08X limit_high=%08X\n", + gs, cpu_state.seg_gs.limit, cpu_state.seg_gs.access, cpu_state.seg_gs.limit_low, cpu_state.seg_gs.limit_high); + x808x_log("GDT : base=%06X limit=%04X\n", gdt.base, gdt.limit); + x808x_log("LDT : base=%06X limit=%04X\n", ldt.base, ldt.limit); + x808x_log("IDT : base=%06X limit=%04X\n", idt.base, idt.limit); + x808x_log("TR : base=%06X limit=%04X\n", tr.base, tr.limit); + x808x_log("386 in %s mode: %i-bit data, %-i-bit stack\n", + (msw & 1) ? ((cpu_state.eflags & VM_FLAG) ? "V86" : "protected") : "real", + (use32) ? 32 : 16, (stack32) ? 32 : 16); + x808x_log("CR0=%08X CR2=%08X CR3=%08X CR4=%08x\n", cr0, cr2, cr3, cr4); + x808x_log("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n", + EAX, EBX, ECX, EDX, EDI, ESI, EBP, ESP); } else { - x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); - x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", - AX, BX, CX, DX, DI, SI, BP, SP); + x808x_log("808x/286 in %s mode\n", (msw & 1) ? "protected" : "real"); + x808x_log("AX=%04X BX=%04X CX=%04X DX=%04X DI=%04X SI=%04X BP=%04X SP=%04X\n", + AX, BX, CX, DX, DI, SI, BP, SP); } x808x_log("Entries in readlookup : %i writelookup : %i\n", readlnum, writelnum); x87_dumpregs(); indump = 0; } #else -#define x808x_log(fmt, ...) +# define x808x_log(fmt, ...) #endif - /* Preparation of the various arrays needed to speed up the MOD and R/M work. */ static void makemod1table(void) @@ -160,143 +156,141 @@ makemod1table(void) mod1add[1][5] = &zero; mod1add[1][6] = &zero; mod1add[1][7] = &zero; - mod1seg[0] = &ds; - mod1seg[1] = &ds; - mod1seg[2] = &ss; - mod1seg[3] = &ss; - mod1seg[4] = &ds; - mod1seg[5] = &ds; - mod1seg[6] = &ss; - mod1seg[7] = &ds; + mod1seg[0] = &ds; + mod1seg[1] = &ds; + mod1seg[2] = &ss; + mod1seg[3] = &ss; + mod1seg[4] = &ds; + mod1seg[5] = &ds; + mod1seg[6] = &ss; + mod1seg[7] = &ds; } - /* Prepare the ZNP table needed to speed up the setting of the Z, N, and P cpu_state.flags. */ static void makeznptable(void) { int c, d, e; for (c = 0; c < 256; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable8[c] = 0; - else - znptable8[c] = P_FLAG; + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable8[c] = 0; + else + znptable8[c] = P_FLAG; #ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); + if (c == 0xb1) + x808x_log("znp8 b1 = %i %02X\n", d, znptable8[c]); #endif - if (!c) - znptable8[c] |= Z_FLAG; - if (c & 0x80) - znptable8[c] |= N_FLAG; + if (!c) + znptable8[c] |= Z_FLAG; + if (c & 0x80) + znptable8[c] |= N_FLAG; } for (c = 0; c < 65536; c++) { - d = 0; - for (e = 0; e < 8; e++) { - if (c & (1 << e)) - d++; - } - if (d & 1) - znptable16[c] = 0; - else - znptable16[c] = P_FLAG; + d = 0; + for (e = 0; e < 8; e++) { + if (c & (1 << e)) + d++; + } + if (d & 1) + znptable16[c] = 0; + else + znptable16[c] = P_FLAG; #ifdef ENABLE_808X_LOG - if (c == 0xb1) - x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); - if (c == 0x65b1) - x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); + if (c == 0xb1) + x808x_log("znp16 b1 = %i %02X\n", d, znptable16[c]); + if (c == 0x65b1) + x808x_log("znp16 65b1 = %i %02X\n", d, znptable16[c]); #endif - if (!c) - znptable16[c] |= Z_FLAG; - if (c & 0x8000) - znptable16[c] |= N_FLAG; + if (!c) + znptable16[c] |= Z_FLAG; + if (c & 0x8000) + znptable16[c] |= N_FLAG; } } - /* Common reset function. */ static void reset_common(int hard) { #ifdef ENABLE_808X_LOG if (hard) - x808x_log("x86 reset\n"); + x808x_log("x86 reset\n"); #endif if (!hard && reset_on_hlt) { - hlt_reset_pending++; - pclog("hlt_reset_pending = %i\n", hlt_reset_pending); - if (hlt_reset_pending == 2) - hlt_reset_pending = 0; - else - return; + hlt_reset_pending++; + pclog("hlt_reset_pending = %i\n", hlt_reset_pending); + if (hlt_reset_pending == 2) + hlt_reset_pending = 0; + else + return; } /* Make sure to gracefully leave SMM. */ if (in_smm) - leave_smm(); + leave_smm(); /* Needed for the ALi M1533. */ if (is486 && (hard || soft_reset_pci)) { - pci_reset(); - if (!hard && soft_reset_pci) { - dma_reset(); - /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, - and vice-versa. */ - dma_set_at(is286); - device_reset_all(); - } + pci_reset(); + if (!hard && soft_reset_pci) { + dma_reset(); + /* TODO: Hack, but will do for time being, because all AT machines currently are 286+, + and vice-versa. */ + dma_set_at(is286); + device_reset_all(); + } } - use32 = 0; + use32 = 0; cpu_cur_status = 0; - stack32 = 0; - msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); - msw = 0; + stack32 = 0; + msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); + msw = 0; if (hascache) - cr0 = 1 << 30; + cr0 = 1 << 30; else - cr0 = 0; + cr0 = 0; cpu_cache_int_enabled = 0; cpu_update_waitstates(); - cr4 = 0; + cr4 = 0; cpu_state.eflags = 0; - cgate32 = 0; + cgate32 = 0; if (is286) { - loadcs(0xF000); - cpu_state.pc = 0xFFF0; - rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; - if (is6117) - rammask |= 0x03000000; + loadcs(0xF000); + cpu_state.pc = 0xFFF0; + rammask = cpu_16bitbus ? 0xFFFFFF : 0xFFFFFFFF; + if (is6117) + rammask |= 0x03000000; } - idt.base = 0; + idt.base = 0; cpu_state.flags = 2; - trap = 0; + trap = 0; idt.limit = is386 ? 0x03ff : 0xffff; if (is386 || hard) - EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; + EAX = EBX = ECX = EDX = ESI = EDI = EBP = ESP = 0; if (hard) { - makeznptable(); - resetreadlookup(); - makemod1table(); - cpu_set_edx(); - mmu_perm = 4; + makeznptable(); + resetreadlookup(); + makemod1table(); + cpu_set_edx(); + mmu_perm = 4; } x86seg_reset(); #ifdef USE_DYNAREC if (hard) - codegen_reset(); + codegen_reset(); #endif if (!hard) - flushmmucache(); + flushmmucache(); x86_was_reset = 1; cpu_alt_reset = 0; @@ -304,12 +298,12 @@ reset_common(int hard) in_smm = smi_latched = 0; smi_line = smm_in_hlt = 0; - smi_block = 0; + smi_block = 0; if (hard) { - if (is486) - smbase = is_am486dxl ? 0x00060000 : 0x00030000; - ppi_reset(); + if (is486) + smbase = is_am486dxl ? 0x00060000 : 0x00030000; + ppi_reset(); } in_sys = 0; @@ -317,17 +311,16 @@ reset_common(int hard) alt_access = cpu_end_block_after_ins = 0; if (hard) { - reset_on_hlt = hlt_reset_pending = 0; - cache_index = 0; - memset(_tr, 0x00, sizeof(_tr)); - memset(_cache, 0x00, sizeof(_cache)); + reset_on_hlt = hlt_reset_pending = 0; + cache_index = 0; + memset(_tr, 0x00, sizeof(_tr)); + memset(_cache, 0x00, sizeof(_cache)); } if (!is286) - reset_808x(hard); + reset_808x(hard); } - /* Hard reset. */ void resetx86(void) @@ -337,13 +330,12 @@ resetx86(void) soft_reset_mask = 0; } - /* Soft reset. */ void softresetx86(void) { if (soft_reset_mask) - return; + return; if (ibm8514_enabled || xga_enabled) vga_on = 1; @@ -351,7 +343,6 @@ softresetx86(void) reset_common(0); } - /* Actual hard reset. */ void hardresetx86(void) diff --git a/src/cpu/x86.h b/src/cpu/x86.h index b468ba4aa..337619fa4 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -7,77 +7,78 @@ This distinction is used by the dynarec; a block that hits an 'expected' exception would be compiled, a block that hits an 'unexpected' exception would be rejected so that we don't end up with an unnecessarily short block*/ -#define ABRT_EXPECTED 0x80 +#define ABRT_EXPECTED 0x80 -extern uint8_t opcode, opcode2; -extern uint8_t flags_p; -extern uint8_t znptable8[256]; +extern uint8_t opcode, opcode2; +extern uint8_t flags_p; +extern uint8_t znptable8[256]; -extern uint16_t zero, oldcs; -extern uint16_t lastcs, lastpc; +extern uint16_t zero, oldcs; +extern uint16_t lastcs, lastpc; extern uint16_t *mod1add[2][8]; -extern uint16_t znptable16[65536]; +extern uint16_t znptable16[65536]; -extern int x86_was_reset, trap; -extern int codegen_flat_ss, codegen_flat_ds; -extern int timetolive, keyboardtimer, trap; -extern int optype, stack32; -extern int oldcpl, cgate32, cpl_override; -extern int nmi_enable; -extern int oddeven, inttype; +extern int x86_was_reset, trap; +extern int codegen_flat_ss, codegen_flat_ds; +extern int timetolive, keyboardtimer, trap; +extern int optype, stack32; +extern int oldcpl, cgate32, cpl_override; +extern int nmi_enable; +extern int oddeven, inttype; -extern uint32_t use32; -extern uint32_t rmdat, easeg; -extern uint32_t oxpc, flags_zn; -extern uint32_t abrt_error; -extern uint32_t backupregs[16]; +extern uint32_t use32; +extern uint32_t rmdat, easeg; +extern uint32_t oxpc, flags_zn; +extern uint32_t abrt_error; +extern uint32_t backupregs[16]; extern uint32_t *mod1seg[8]; extern uint32_t *eal_r, *eal_w; -#define fetchdat rmdat +#define fetchdat rmdat #define setznp168 setznp16 -#define getr8(r) ((r&4)?cpu_state.regs[r&3].b.h:cpu_state.regs[r&3].b.l) -#define getr16(r) cpu_state.regs[r].w -#define getr32(r) cpu_state.regs[r].l +#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) +#define getr16(r) cpu_state.regs[r].w +#define getr32(r) cpu_state.regs[r].l -#define setr8(r,v) if (r&4) cpu_state.regs[r&3].b.h=v; \ - else cpu_state.regs[r&3].b.l=v; -#define setr16(r,v) cpu_state.regs[r].w=v -#define setr32(r,v) cpu_state.regs[r].l=v +#define setr8(r, v) \ + if (r & 4) \ + cpu_state.regs[r & 3].b.h = v; \ + else \ + cpu_state.regs[r & 3].b.l = v; +#define setr16(r, v) cpu_state.regs[r].w = v +#define setr32(r, v) cpu_state.regs[r].l = v -#define fetchea() { \ - rmdat = readmemb(cs + pc); \ - pc++; \ - reg = (rmdat >> 3) & 7; \ - mod = (rmdat >> 6) & 3; \ - rm = rmdat & 7; \ - if (mod!=3) \ - fetcheal(); \ - } +#define fetchea() \ + { \ + rmdat = readmemb(cs + pc); \ + pc++; \ + reg = (rmdat >> 3) & 7; \ + mod = (rmdat >> 6) & 3; \ + rm = rmdat & 7; \ + if (mod != 3) \ + fetcheal(); \ + } -#define JMP 1 -#define CALL 2 -#define IRET 3 +#define JMP 1 +#define CALL 2 +#define IRET 3 #define OPTYPE_INT 4 - -enum -{ - ABRT_NONE = 0, - ABRT_GEN, - ABRT_TS = 0xA, - ABRT_NP = 0xB, - ABRT_SS = 0xC, - ABRT_GPF = 0xD, - ABRT_PF = 0xE, - ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ +enum { + ABRT_NONE = 0, + ABRT_GEN, + ABRT_TS = 0xA, + ABRT_NP = 0xB, + ABRT_SS = 0xC, + ABRT_GPF = 0xD, + ABRT_PF = 0xE, + ABRT_DE = 0x40 /* INT 0, but we have to distinguish it from ABRT_NONE. */ }; - -extern void x86_doabrt(int x86_abrt); -extern void x86illegal(void); -extern void x86seg_reset(void); -extern void x86gpf(char *s, uint16_t error); -extern void x86gpf_expected(char *s, uint16_t error); +extern void x86_doabrt(int x86_abrt); +extern void x86illegal(void); +extern void x86seg_reset(void); +extern void x86gpf(char *s, uint16_t error); +extern void x86gpf_expected(char *s, uint16_t error); diff --git a/src/cpu/x86_flags.h b/src/cpu/x86_flags.h index 6b2293322..b8b1a706a 100644 --- a/src/cpu/x86_flags.h +++ b/src/cpu/x86_flags.h @@ -1,781 +1,823 @@ extern int tempc; -enum -{ - FLAGS_UNKNOWN, +enum { + FLAGS_UNKNOWN, - FLAGS_ZN8, - FLAGS_ZN16, - FLAGS_ZN32, + FLAGS_ZN8, + FLAGS_ZN16, + FLAGS_ZN32, - FLAGS_ADD8, - FLAGS_ADD16, - FLAGS_ADD32, + FLAGS_ADD8, + FLAGS_ADD16, + FLAGS_ADD32, - FLAGS_SUB8, - FLAGS_SUB16, - FLAGS_SUB32, + FLAGS_SUB8, + FLAGS_SUB16, + FLAGS_SUB32, - FLAGS_SHL8, - FLAGS_SHL16, - FLAGS_SHL32, + FLAGS_SHL8, + FLAGS_SHL16, + FLAGS_SHL32, - FLAGS_SHR8, - FLAGS_SHR16, - FLAGS_SHR32, + FLAGS_SHR8, + FLAGS_SHR16, + FLAGS_SHR32, - FLAGS_SAR8, - FLAGS_SAR16, - FLAGS_SAR32, + FLAGS_SAR8, + FLAGS_SAR16, + FLAGS_SAR32, #ifdef USE_NEW_DYNAREC - FLAGS_ROL8, - FLAGS_ROL16, - FLAGS_ROL32, + FLAGS_ROL8, + FLAGS_ROL16, + FLAGS_ROL32, - FLAGS_ROR8, - FLAGS_ROR16, - FLAGS_ROR32, + FLAGS_ROR8, + FLAGS_ROR16, + FLAGS_ROR32, #endif - FLAGS_INC8, - FLAGS_INC16, - FLAGS_INC32, + FLAGS_INC8, + FLAGS_INC16, + FLAGS_INC32, - FLAGS_DEC8, - FLAGS_DEC16, - FLAGS_DEC32 + FLAGS_DEC8, + FLAGS_DEC16, + FLAGS_DEC32 #ifdef USE_NEW_DYNAREC -, + , - FLAGS_ADC8, - FLAGS_ADC16, - FLAGS_ADC32, + FLAGS_ADC8, + FLAGS_ADC16, + FLAGS_ADC32, - FLAGS_SBC8, - FLAGS_SBC16, - FLAGS_SBC32 + FLAGS_SBC8, + FLAGS_SBC16, + FLAGS_SBC32 #endif }; -static __inline int ZF_SET(void) +static __inline int +ZF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: #endif - return !cpu_state.flags_res; + return !cpu_state.flags_res; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & Z_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & Z_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int NF_SET(void) +static __inline int +NF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_SBC8: + case FLAGS_ADC8: + case FLAGS_SBC8: #endif - return cpu_state.flags_res & 0x80; + return cpu_state.flags_res & 0x80; - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC16: - case FLAGS_SBC16: + case FLAGS_ADC16: + case FLAGS_SBC16: #endif - return cpu_state.flags_res & 0x8000; + return cpu_state.flags_res & 0x8000; - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC32: - case FLAGS_SBC32: + case FLAGS_ADC32: + case FLAGS_SBC32: #endif - return cpu_state.flags_res & 0x80000000; + return cpu_state.flags_res & 0x80000000; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & N_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & N_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int PF_SET(void) +static __inline int +PF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - case FLAGS_ADC16: - case FLAGS_ADC32: - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: + case FLAGS_ADC8: + case FLAGS_ADC16: + case FLAGS_ADC32: + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: #endif - return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; + return znptable8[cpu_state.flags_res & 0xff] & P_FLAG; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & P_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & P_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int VF_SET(void) +static __inline int +VF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + return 0; #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: + case FLAGS_ADC8: #endif - case FLAGS_ADD8: - case FLAGS_INC8: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_ADD8: + case FLAGS_INC8: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC16: + case FLAGS_ADC16: #endif - case FLAGS_ADD16: - case FLAGS_INC16: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_ADD16: + case FLAGS_INC16: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x8000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC32: + case FLAGS_ADC32: #endif - case FLAGS_ADD32: - case FLAGS_INC32: - return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_ADD32: + case FLAGS_INC32: + return !((cpu_state.flags_op1 ^ cpu_state.flags_op2) & 0x80000000) && ((cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: + case FLAGS_SBC8: #endif - case FLAGS_SUB8: - case FLAGS_DEC8: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); + case FLAGS_SUB8: + case FLAGS_DEC8: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC16: + case FLAGS_SBC16: #endif - case FLAGS_SUB16: - case FLAGS_DEC16: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); + case FLAGS_SUB16: + case FLAGS_DEC16: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x8000); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC32: + case FLAGS_SBC32: #endif - case FLAGS_SUB32: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); + case FLAGS_SUB32: + case FLAGS_DEC32: + return ((cpu_state.flags_op1 ^ cpu_state.flags_op2) & (cpu_state.flags_op1 ^ cpu_state.flags_res) & 0x80000000); - case FLAGS_SHL8: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); - case FLAGS_SHL16: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); - case FLAGS_SHL32: - return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); + case FLAGS_SHL8: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80); + case FLAGS_SHL16: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x8000); + case FLAGS_SHL32: + return (((cpu_state.flags_op1 << cpu_state.flags_op2) ^ (cpu_state.flags_op1 << (cpu_state.flags_op2 - 1))) & 0x80000000); - case FLAGS_SHR8: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); - case FLAGS_SHR16: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); - case FLAGS_SHR32: - return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); + case FLAGS_SHR8: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80)); + case FLAGS_SHR16: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x8000)); + case FLAGS_SHR32: + return ((cpu_state.flags_op2 == 1) && (cpu_state.flags_op1 & 0x80000000)); #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; - case FLAGS_ROL16: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; - case FLAGS_ROL32: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; + case FLAGS_ROL8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 7)) & 1; + case FLAGS_ROL16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 15)) & 1; + case FLAGS_ROL32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 31)) & 1; - case FLAGS_ROR8: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; - case FLAGS_ROR16: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; - case FLAGS_ROR32: - return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; + case FLAGS_ROR8: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40; + case FLAGS_ROR16: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x4000; + case FLAGS_ROR32: + return (cpu_state.flags_res ^ (cpu_state.flags_res >> 1)) & 0x40000000; #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & V_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & V_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int AF_SET(void) +static __inline int +AF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - return 0; + switch (cpu_state.flags_op) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + return 0; - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + return ((cpu_state.flags_op1 & 0xF) + (cpu_state.flags_op2 & 0xF)) & 0x10; #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || - ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return ((cpu_state.flags_res & 0xf) < (cpu_state.flags_op1 & 0xf)) || ((cpu_state.flags_res & 0xf) == (cpu_state.flags_op1 & 0xf) && cpu_state.flags_op2 == 0xffffffff); #endif - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + return ((cpu_state.flags_op1 & 0xF) - (cpu_state.flags_op2 & 0xF)) & 0x10; #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || - ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return ((cpu_state.flags_op1 & 0xf) < (cpu_state.flags_op2 & 0xf)) || ((cpu_state.flags_op1 & 0xf) == (cpu_state.flags_op2 & 0xf) && (cpu_state.flags_res & 0xf) != 0); - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - case FLAGS_ROR8: - case FLAGS_ROR16: - case FLAGS_ROR32: + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + case FLAGS_ROR8: + case FLAGS_ROR16: + case FLAGS_ROR32: #endif - case FLAGS_UNKNOWN: - return cpu_state.flags & A_FLAG; + case FLAGS_UNKNOWN: + return cpu_state.flags & A_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline int CF_SET(void) +static __inline int +CF_SET(void) { - switch (cpu_state.flags_op) - { - case FLAGS_ADD8: - return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; - case FLAGS_ADD16: - return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; - case FLAGS_ADD32: - return (cpu_state.flags_res < cpu_state.flags_op1); + switch (cpu_state.flags_op) { + case FLAGS_ADD8: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x100) ? 1 : 0; + case FLAGS_ADD16: + return ((cpu_state.flags_op1 + cpu_state.flags_op2) & 0x10000) ? 1 : 0; + case FLAGS_ADD32: + return (cpu_state.flags_res < cpu_state.flags_op1); #ifdef USE_NEW_DYNAREC - case FLAGS_ADC8: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); - case FLAGS_ADC16: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); - case FLAGS_ADC32: - return (cpu_state.flags_res < cpu_state.flags_op1) || - (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); + case FLAGS_ADC8: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xff); + case FLAGS_ADC16: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffff); + case FLAGS_ADC32: + return (cpu_state.flags_res < cpu_state.flags_op1) || (cpu_state.flags_res == cpu_state.flags_op1 && cpu_state.flags_op2 == 0xffffffff); #endif - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - return (cpu_state.flags_op1 < cpu_state.flags_op2); + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + return (cpu_state.flags_op1 < cpu_state.flags_op2); #ifdef USE_NEW_DYNAREC - case FLAGS_SBC8: - case FLAGS_SBC16: - case FLAGS_SBC32: - return (cpu_state.flags_op1 < cpu_state.flags_op2) || - (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); + case FLAGS_SBC8: + case FLAGS_SBC16: + case FLAGS_SBC32: + return (cpu_state.flags_op1 < cpu_state.flags_op2) || (cpu_state.flags_op1 == cpu_state.flags_op2 && cpu_state.flags_res != 0); #endif - case FLAGS_SHL8: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; - case FLAGS_SHL16: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; - case FLAGS_SHL32: - return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; + case FLAGS_SHL8: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80) ? 1 : 0; + case FLAGS_SHL16: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x8000) ? 1 : 0; + case FLAGS_SHL32: + return ((cpu_state.flags_op1 << (cpu_state.flags_op2 - 1)) & 0x80000000) ? 1 : 0; - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + return (cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR8: - return ((int8_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR16: - return ((int16_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_SAR32: - return ((int32_t)cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR8: + return ((int8_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR16: + return ((int16_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; + case FLAGS_SAR32: + return ((int32_t) cpu_state.flags_op1 >> (cpu_state.flags_op2 - 1)) & 1; - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - return 0; + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + return 0; #ifdef USE_NEW_DYNAREC - case FLAGS_ROL8: - case FLAGS_ROL16: - case FLAGS_ROL32: - return cpu_state.flags_res & 1; + case FLAGS_ROL8: + case FLAGS_ROL16: + case FLAGS_ROL32: + return cpu_state.flags_res & 1; - case FLAGS_ROR8: - return (cpu_state.flags_res & 0x80) ? 1 : 0; - case FLAGS_ROR16: - return (cpu_state.flags_res & 0x8000) ? 1 :0; - case FLAGS_ROR32: - return (cpu_state.flags_res & 0x80000000) ? 1 : 0; + case FLAGS_ROR8: + return (cpu_state.flags_res & 0x80) ? 1 : 0; + case FLAGS_ROR16: + return (cpu_state.flags_res & 0x8000) ? 1 : 0; + case FLAGS_ROR32: + return (cpu_state.flags_res & 0x80000000) ? 1 : 0; #endif - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_UNKNOWN: - return cpu_state.flags & C_FLAG; + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_UNKNOWN: + return cpu_state.flags & C_FLAG; #ifndef USE_NEW_DYNAREC - default: - return 0; + default: + return 0; #endif - } + } #ifdef USE_NEW_DYNAREC - return 0; + return 0; #endif } -static __inline void flags_rebuild(void) -{ - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - uint16_t tempf = 0; - if (CF_SET()) tempf |= C_FLAG; - if (PF_SET()) tempf |= P_FLAG; - if (AF_SET()) tempf |= A_FLAG; - if (ZF_SET()) tempf |= Z_FLAG; - if (NF_SET()) tempf |= N_FLAG; - if (VF_SET()) tempf |= V_FLAG; - cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; - cpu_state.flags_op = FLAGS_UNKNOWN; - } -} - -static __inline void flags_extract(void) +static __inline void +flags_rebuild(void) { + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + uint16_t tempf = 0; + if (CF_SET()) + tempf |= C_FLAG; + if (PF_SET()) + tempf |= P_FLAG; + if (AF_SET()) + tempf |= A_FLAG; + if (ZF_SET()) + tempf |= Z_FLAG; + if (NF_SET()) + tempf |= N_FLAG; + if (VF_SET()) + tempf |= V_FLAG; + cpu_state.flags = (cpu_state.flags & ~0x8d5) | tempf; cpu_state.flags_op = FLAGS_UNKNOWN; + } } -static __inline void flags_rebuild_c(void) +static __inline void +flags_extract(void) { - if (cpu_state.flags_op != FLAGS_UNKNOWN) - { - if (CF_SET()) - cpu_state.flags |= C_FLAG; - else - cpu_state.flags &= ~C_FLAG; - } + cpu_state.flags_op = FLAGS_UNKNOWN; +} + +static __inline void +flags_rebuild_c(void) +{ + if (cpu_state.flags_op != FLAGS_UNKNOWN) { + if (CF_SET()) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + } } #ifdef USE_NEW_DYNAREC -static __inline int flags_res_valid(void) +static __inline int +flags_res_valid(void) { - if (cpu_state.flags_op == FLAGS_UNKNOWN || - (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) - return 0; + if (cpu_state.flags_op == FLAGS_UNKNOWN || (cpu_state.flags_op >= FLAGS_ROL8 && cpu_state.flags_op <= FLAGS_ROR32)) + return 0; - return 1; + return 1; } #endif -static __inline void setznp8(uint8_t val) +static __inline void +setznp8(uint8_t val) { - cpu_state.flags_op = FLAGS_ZN8; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN8; + cpu_state.flags_res = val; } -static __inline void setznp16(uint16_t val) +static __inline void +setznp16(uint16_t val) { - cpu_state.flags_op = FLAGS_ZN16; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN16; + cpu_state.flags_res = val; } -static __inline void setznp32(uint32_t val) +static __inline void +setznp32(uint32_t val) { - cpu_state.flags_op = FLAGS_ZN32; - cpu_state.flags_res = val; + cpu_state.flags_op = FLAGS_ZN32; + cpu_state.flags_res = val; } #define set_flags_shift(op, orig, shift, res) \ - cpu_state.flags_op = op; \ - cpu_state.flags_res = res; \ - cpu_state.flags_op1 = orig; \ - cpu_state.flags_op2 = shift; + cpu_state.flags_op = op; \ + cpu_state.flags_res = res; \ + cpu_state.flags_op1 = orig; \ + cpu_state.flags_op2 = shift; #ifdef USE_NEW_DYNAREC -#define set_flags_rotate(op, res) \ - cpu_state.flags_op = op; \ +# define set_flags_rotate(op, res) \ + cpu_state.flags_op = op; \ cpu_state.flags_res = res; #endif -static __inline void setadd8(uint8_t a, uint8_t b) +static __inline void +setadd8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_ADD8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xff; + cpu_state.flags_op = FLAGS_ADD8; } -static __inline void setadd16(uint16_t a, uint16_t b) +static __inline void +setadd16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_ADD16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xffff; + cpu_state.flags_op = FLAGS_ADD16; } -static __inline void setadd32(uint32_t a, uint32_t b) +static __inline void +setadd32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_ADD32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b; + cpu_state.flags_op = FLAGS_ADD32; } -static __inline void setadd8nc(uint8_t a, uint8_t b) +static __inline void +setadd8nc(uint8_t a, uint8_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xff; - cpu_state.flags_op = FLAGS_INC8; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xff; + cpu_state.flags_op = FLAGS_INC8; } -static __inline void setadd16nc(uint16_t a, uint16_t b) +static __inline void +setadd16nc(uint16_t a, uint16_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b) & 0xffff; - cpu_state.flags_op = FLAGS_INC16; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b) & 0xffff; + cpu_state.flags_op = FLAGS_INC16; } -static __inline void setadd32nc(uint32_t a, uint32_t b) +static __inline void +setadd32nc(uint32_t a, uint32_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b; - cpu_state.flags_op = FLAGS_INC32; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b; + cpu_state.flags_op = FLAGS_INC32; } -static __inline void setsub8(uint8_t a, uint8_t b) +static __inline void +setsub8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_SUB8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xff; + cpu_state.flags_op = FLAGS_SUB8; } -static __inline void setsub16(uint16_t a, uint16_t b) +static __inline void +setsub16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_SUB16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xffff; + cpu_state.flags_op = FLAGS_SUB16; } -static __inline void setsub32(uint32_t a, uint32_t b) +static __inline void +setsub32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_SUB32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - b; + cpu_state.flags_op = FLAGS_SUB32; } -static __inline void setsub8nc(uint8_t a, uint8_t b) +static __inline void +setsub8nc(uint8_t a, uint8_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xff; - cpu_state.flags_op = FLAGS_DEC8; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xff; + cpu_state.flags_op = FLAGS_DEC8; } -static __inline void setsub16nc(uint16_t a, uint16_t b) +static __inline void +setsub16nc(uint16_t a, uint16_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - b) & 0xffff; - cpu_state.flags_op = FLAGS_DEC16; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - b) & 0xffff; + cpu_state.flags_op = FLAGS_DEC16; } -static __inline void setsub32nc(uint32_t a, uint32_t b) +static __inline void +setsub32nc(uint32_t a, uint32_t b) { - flags_rebuild_c(); - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - b; - cpu_state.flags_op = FLAGS_DEC32; + flags_rebuild_c(); + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - b; + cpu_state.flags_op = FLAGS_DEC32; } #ifdef USE_NEW_DYNAREC -static __inline void setadc8(uint8_t a, uint8_t b) +static __inline void +setadc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xff; - cpu_state.flags_op = FLAGS_ADC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xff; + cpu_state.flags_op = FLAGS_ADC8; } -static __inline void setadc16(uint16_t a, uint16_t b) +static __inline void +setadc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a + b + tempc) & 0xffff; - cpu_state.flags_op = FLAGS_ADC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a + b + tempc) & 0xffff; + cpu_state.flags_op = FLAGS_ADC16; } -static __inline void setadc32(uint32_t a, uint32_t b) +static __inline void +setadc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a + b + tempc; - cpu_state.flags_op = FLAGS_ADC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a + b + tempc; + cpu_state.flags_op = FLAGS_ADC32; } -static __inline void setsbc8(uint8_t a, uint8_t b) +static __inline void +setsbc8(uint8_t a, uint8_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xff; - cpu_state.flags_op = FLAGS_SBC8; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xff; + cpu_state.flags_op = FLAGS_SBC8; } -static __inline void setsbc16(uint16_t a, uint16_t b) +static __inline void +setsbc16(uint16_t a, uint16_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = (a - (b + tempc)) & 0xffff; - cpu_state.flags_op = FLAGS_SBC16; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = (a - (b + tempc)) & 0xffff; + cpu_state.flags_op = FLAGS_SBC16; } -static __inline void setsbc32(uint32_t a, uint32_t b) +static __inline void +setsbc32(uint32_t a, uint32_t b) { - cpu_state.flags_op1 = a; - cpu_state.flags_op2 = b; - cpu_state.flags_res = a - (b + tempc); - cpu_state.flags_op = FLAGS_SBC32; + cpu_state.flags_op1 = a; + cpu_state.flags_op2 = b; + cpu_state.flags_res = a - (b + tempc); + cpu_state.flags_op = FLAGS_SBC32; } #else -static __inline void setadc8(uint8_t a, uint8_t b) +static __inline void +setadc8(uint8_t a, uint8_t b) { - uint16_t c=(uint16_t)a+(uint16_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable8[c&0xFF]; - if (c&0x100) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x80)&&((a^c)&0x80)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; + uint16_t c = (uint16_t) a + (uint16_t) b + tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable8[c & 0xFF]; + if (c & 0x100) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x80) && ((a ^ c) & 0x80)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } -static __inline void setadc16(uint16_t a, uint16_t b) +static __inline void +setadc16(uint16_t a, uint16_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=znptable16[c&0xFFFF]; - if (c&0x10000) cpu_state.flags|=C_FLAG; - if (!((a^b)&0x8000)&&((a^c)&0x8000)) cpu_state.flags|=V_FLAG; - if (((a&0xF)+(b&0xF))&0x10) cpu_state.flags|=A_FLAG; + uint32_t c = (uint32_t) a + (uint32_t) b + tempc; + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= znptable16[c & 0xFFFF]; + if (c & 0x10000) + cpu_state.flags |= C_FLAG; + if (!((a ^ b) & 0x8000) && ((a ^ c) & 0x8000)) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) + (b & 0xF)) & 0x10) + cpu_state.flags |= A_FLAG; } -static __inline void setadc32(uint32_t a, uint32_t b) +static __inline void +setadc32(uint32_t a, uint32_t b) { - uint32_t c=(uint32_t)a+(uint32_t)b+tempc; - cpu_state.flags_op = FLAGS_UNKNOWN; - cpu_state.flags&=~0x8D5; - cpu_state.flags|=((c&0x80000000)?N_FLAG:((!c)?Z_FLAG:0)); - cpu_state.flags|=(znptable8[c&0xFF]&P_FLAG); - if ((ca) || (c==a && tempc)) cpu_state.flags|=C_FLAG; - if ((a^b)&(a^c)&0x80000000) cpu_state.flags|=V_FLAG; - if (((a&0xF)-((b&0xF)+tempc))&0x10) cpu_state.flags|=A_FLAG; + uint32_t c = (uint32_t) a - (((uint32_t) b) + tempc); + cpu_state.flags_op = FLAGS_UNKNOWN; + cpu_state.flags &= ~0x8D5; + cpu_state.flags |= ((c & 0x80000000) ? N_FLAG : ((!c) ? Z_FLAG : 0)); + cpu_state.flags |= (znptable8[c & 0xFF] & P_FLAG); + if ((c > a) || (c == a && tempc)) + cpu_state.flags |= C_FLAG; + if ((a ^ b) & (a ^ c) & 0x80000000) + cpu_state.flags |= V_FLAG; + if (((a & 0xF) - ((b & 0xF) + tempc)) & 0x10) + cpu_state.flags |= A_FLAG; } #endif diff --git a/src/cpu/x86_ops.h b/src/cpu/x86_ops.h index a1ab95125..a5e82d78e 100644 --- a/src/cpu/x86_ops.h +++ b/src/cpu/x86_ops.h @@ -39,16 +39,14 @@ #ifndef _X86_OPS_H #define _X86_OPS_H - -#define UN_USED(x) (void)(x) - +#define UN_USED(x) (void) (x) typedef int (*OpFn)(uint32_t fetchdat); #ifdef USE_DYNAREC void x86_setopcodes(const OpFn *opcodes, const OpFn *opcodes_0f, - const OpFn *dynarec_opcodes, - const OpFn *dynarec_opcodes_0f); + const OpFn *dynarec_opcodes, + const OpFn *dynarec_opcodes_0f); extern const OpFn *x86_dynarec_opcodes; extern const OpFn *x86_dynarec_opcodes_0f; @@ -92,10 +90,10 @@ extern const OpFn dynarec_ops_winchip2_0f[1024]; extern const OpFn dynarec_ops_pentium_0f[1024]; extern const OpFn dynarec_ops_pentiummmx_0f[1024]; -#if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) +# if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) extern const OpFn dynarec_ops_c6x86_0f[1024]; extern const OpFn dynarec_ops_c6x86mx_0f[1024]; -#endif +# endif extern const OpFn dynarec_ops_k6_0f[1024]; extern const OpFn dynarec_ops_k62_0f[1024]; @@ -253,9 +251,9 @@ extern const OpFn ops_REPNE[1024]; extern const OpFn ops_3DNOW[256]; extern const OpFn ops_3DNOWE[256]; -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) #endif /*_X86_OPS_H*/ diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index d24a6cc33..ca1f9c80a 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -1,360 +1,381 @@ #include -static int opPREFETCH_a16(uint32_t fetchdat) +static int +opPREFETCH_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + CLOCK_CYCLES(1); + return 0; +} +static int +opPREFETCH_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + + CLOCK_CYCLES(1); + return 0; +} + +static int +opFEMMS(uint32_t fetchdat) +{ + ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(1); + return 0; +} + +static int +opPAVGUSB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + + return 0; +} +static int +opPF2ID(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0]; + cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1]; + + return 0; +} +static int +opPF2IW(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0]; + cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1]; + + return 0; +} +static int +opPFACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPFNACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPFPNACC(uint32_t fetchdat) +{ + MMX_REG src; + float tempf; + + MMX_GETSRC(); + + tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; + cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; + cpu_state.MM[cpu_reg].f[0] = tempf; + + return 0; +} +static int +opPSWAPD(uint32_t fetchdat) +{ + MMX_REG src; + float tempf, tempf2; + + MMX_GETSRC(); + + /* We have to do this in case source and destination overlap. */ + tempf = src.f[0]; + tempf2 = src.f[1]; + cpu_state.MM[cpu_reg].f[1] = tempf; + cpu_state.MM[cpu_reg].f[0] = tempf2; + + return 0; +} +static int +opPFADD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] += src.f[0]; + cpu_state.MM[cpu_reg].f[1] += src.f[1]; + + return 0; +} +static int +opPFCMPEQ(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFCMPGE(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFCMPGT(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + + return 0; +} +static int +opPFMAX(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int +opPFMIN(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) + cpu_state.MM[cpu_reg].f[1] = src.f[1]; + + return 0; +} +static int +opPFMUL(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] *= src.f[0]; + cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + + return 0; +} +static int +opPFRCP(uint32_t fetchdat) +{ + union { + uint32_t i; + float f; + } src; + + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; CLOCK_CYCLES(1); - return 0; -} -static int opPREFETCH_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - CLOCK_CYCLES(1); - return 0; -} + cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; -static int opFEMMS(uint32_t fetchdat) -{ - ILLEGAL_ON(!cpu_has_feature(CPU_FEATURE_MMX)); - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(1); - return 0; -} - -static int opPAVGUSB(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; - - return 0; -} -static int opPF2ID(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sl[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sl[1] = (int32_t)src.f[1]; - - return 0; -} -static int opPF2IW(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = (int32_t)src.f[0]; - cpu_state.MM[cpu_reg].sw[1] = (int32_t)src.f[1]; - - return 0; -} -static int opPFACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPFNACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPFPNACC(uint32_t fetchdat) -{ - MMX_REG src; - float tempf; - - MMX_GETSRC(); - - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; - - return 0; -} -static int opPSWAPD(uint32_t fetchdat) -{ - MMX_REG src; - float tempf, tempf2; - - MMX_GETSRC(); - - /* We have to do this in case source and destination overlap. */ - tempf = src.f[0]; - tempf2 = src.f[1]; - cpu_state.MM[cpu_reg].f[1] = tempf; - cpu_state.MM[cpu_reg].f[0] = tempf2; - - return 0; -} -static int opPFADD(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] += src.f[0]; - cpu_state.MM[cpu_reg].f[1] += src.f[1]; - - return 0; -} -static int opPFCMPEQ(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFCMPGE(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFCMPGT(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; - - return 0; -} -static int opPFMAX(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; - - return 0; -} -static int opPFMIN(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; - - return 0; -} -static int opPFMUL(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] *= src.f[0]; - cpu_state.MM[cpu_reg].f[1] *= src.f[1]; - - return 0; -} -static int opPFRCP(uint32_t fetchdat) -{ - union - { - uint32_t i; - float f; - } src; - - if (cpu_mod == 3) - { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - - cpu_state.MM[cpu_reg].f[0] = 1.0/src.f; - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - - return 0; + return 0; } /*Since opPFRCP() calculates a full precision reciprocal, treat the followup iterations as MOVs*/ -static int opPFRCPIT1(uint32_t fetchdat) +static int +opPFRCPIT1(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } -static int opPFRCPIT2(uint32_t fetchdat) +static int +opPFRCPIT2(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_GETSRC(); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + cpu_state.MM[cpu_reg].f[0] = src.f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1]; - return 0; + return 0; } -static int opPFRSQRT(uint32_t fetchdat) +static int +opPFRSQRT(uint32_t fetchdat) { - union - { - uint32_t i; - float f; - } src; + union { + uint32_t i; + float f; + } src; - if (cpu_mod == 3) - { - src.f = cpu_state.MM[cpu_rm].f[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_READ(cpu_state.ea_seg); - src.i = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } + if (cpu_mod == 3) { + src.f = cpu_state.MM[cpu_rm].f[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.i = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } - cpu_state.MM[cpu_reg].f[0] = 1.0/sqrt(src.f); - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); + cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; - return 0; + return 0; } /*Since opPFRSQRT() calculates a full precision inverse square root, treat the followup iteration as a NOP*/ -static int opPFRSQIT1(uint32_t fetchdat) +static int +opPFRSQIT1(uint32_t fetchdat) { + MMX_REG src; + + MMX_GETSRC(); + UN_USED(src); + + return 0; +} +static int +opPFSUB(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] -= src.f[0]; + cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + + return 0; +} +static int +opPFSUBR(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; + cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + + return 0; +} +static int +opPI2FD(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0]; + cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1]; + + return 0; +} +static int +opPI2FW(uint32_t fetchdat) +{ + MMX_REG src; + + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0]; + cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1]; + + return 0; +} +static int +opPMULHRW(uint32_t fetchdat) +{ + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_GETSRC(); - UN_USED(src); - - return 0; -} -static int opPFSUB(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] -= src.f[0]; - cpu_state.MM[cpu_reg].f[1] -= src.f[1]; - - return 0; -} -static int opPFSUBR(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; - - return 0; -} -static int opPI2FD(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = (float)src.sl[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sl[1]; - - return 0; -} -static int opPI2FW(uint32_t fetchdat) -{ - MMX_REG src; - - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].f[0] = (float)src.sw[0]; - cpu_state.MM[cpu_reg].f[1] = (float)src.sw[1]; - - return 0; -} -static int opPMULHRW(uint32_t fetchdat) -{ - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = (((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = (((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = (((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = (((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)(cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)(cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)(cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)(cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) + 0x8000) >> 16; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; + CLOCK_CYCLES(2); + } + return 0; } const OpFn OP_TABLE(3DNOW)[256] = @@ -405,29 +426,33 @@ const OpFn OP_TABLE(3DNOWE)[256] = /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -static int op3DNOW_a16(uint32_t fetchdat) +static int +op3DNOW_a16(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetch_ea_16(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } -static int op3DNOW_a32(uint32_t fetchdat) +static int +op3DNOW_a32(uint32_t fetchdat) { - uint8_t opcode; + uint8_t opcode; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - opcode = fastreadb(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetch_ea_32(fetchdat); + opcode = fastreadb(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - return x86_opcodes_3DNOW[opcode](0); + return x86_opcodes_3DNOW[opcode](0); } diff --git a/src/cpu/x86_ops_amd.h b/src/cpu/x86_ops_amd.h index 2b640ede4..9e6bcce55 100644 --- a/src/cpu/x86_ops_amd.h +++ b/src/cpu/x86_ops_amd.h @@ -23,16 +23,15 @@ opSYSCALL(uint32_t fetchdat) ret = syscall_op(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int opSYSRET(uint32_t fetchdat) { @@ -43,10 +42,10 @@ opSYSRET(uint32_t fetchdat) ret = sysret(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; diff --git a/src/cpu/x86_ops_arith.h b/src/cpu/x86_ops_arith.h index b56abb26a..41c655d09 100644 --- a/src/cpu/x86_ops_arith.h +++ b/src/cpu/x86_ops_arith.h @@ -1,827 +1,1012 @@ -#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ - static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ - { \ - uint8_t dst; \ - uint8_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = getr8(cpu_rm); \ - src = getr8(cpu_reg); \ - setflags ## 8 flagops; \ - setr8(cpu_rm, operation); \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteab(); if (cpu_state.abrt) return 1; \ - src = getr8(cpu_reg); \ - seteab(operation); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_mr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ - { \ - uint16_t dst; \ - uint16_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].w; \ - src = cpu_state.regs[cpu_reg].w; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_rm].w = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteaw(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].w; \ - seteaw(operation); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 1,0,1,0, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 0); \ - } \ - return 0; \ - } \ - static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ - { \ - uint32_t dst; \ - uint32_t src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod == 3) \ - { \ - dst = cpu_state.regs[cpu_rm].l; \ - src = cpu_state.regs[cpu_reg].l; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_rm].l = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); \ - } \ - else \ - { \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - dst = geteal(); if (cpu_state.abrt) return 1; \ - src = cpu_state.regs[cpu_reg].l; \ - seteal(operation); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - CLOCK_CYCLES(timing_mr); \ - PREFETCH_RUN(timing_rr, 2, rmdat, 0,1,0,1, 1); \ - } \ - return 0; \ - } \ - \ - static int op ## name ## _b_rm_a16(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _b_rm_a32(uint32_t fetchdat) \ - { \ - uint8_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = getr8(cpu_reg); \ - src = geteab(); if (cpu_state.abrt) return 1; \ - setflags ## 8 flagops; \ - setr8(cpu_reg, operation); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _w_rm_a16(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _w_rm_a32(uint32_t fetchdat) \ - { \ - uint16_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].w; \ - src = geteaw(); if (cpu_state.abrt) return 1; \ - setflags ## 16 flagops; \ - cpu_state.regs[cpu_reg].w = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _l_rm_a16(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); \ - return 0; \ - } \ - static int op ## name ## _l_rm_a32(uint32_t fetchdat) \ - { \ - uint32_t dst, src; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - dst = cpu_state.regs[cpu_reg].l; \ - src = geteal(); if (cpu_state.abrt) return 1; \ - setflags ## 32 flagops; \ - cpu_state.regs[cpu_reg].l = operation; \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); \ - return 0; \ - } \ - \ - static int op ## name ## _AL_imm(uint32_t fetchdat) \ - { \ - uint8_t dst = AL; \ - uint8_t src = getbytef(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 8 flagops; \ - AL = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _AX_imm(uint32_t fetchdat) \ - { \ - uint16_t dst = AX; \ - uint16_t src = getwordf(); \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 16 flagops; \ - AX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int op ## name ## _EAX_imm(uint32_t fetchdat) \ - { \ - uint32_t dst = EAX; \ - uint32_t src = getlong(); if (cpu_state.abrt) return 1; \ - if (gettempc) tempc = CF_SET() ? 1 : 0; \ - setflags ## 32 flagops; \ - EAX = operation; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define OP_ARITH(name, operation, setflags, flagops, gettempc) \ + static int op##name##_b_rmw_a16(uint32_t fetchdat) \ + { \ + uint8_t dst; \ + uint8_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ + setflags##8 flagops; \ + setr8(cpu_rm, operation); \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + src = getr8(cpu_reg); \ + seteab(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_mr, 2, rmdat, 1, 0, 1, 0, 0); \ + } \ + return 0; \ + } \ + static int op##name##_b_rmw_a32(uint32_t fetchdat) \ + { \ + uint8_t dst; \ + uint8_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ + setflags##8 flagops; \ + setr8(cpu_rm, operation); \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + src = getr8(cpu_reg); \ + seteab(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_mr, 2, rmdat, 1, 0, 1, 0, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_w_rmw_a16(uint32_t fetchdat) \ + { \ + uint16_t dst; \ + uint16_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_rm].w = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].w; \ + seteaw(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 1, 0, 1, 0, 0); \ + } \ + return 0; \ + } \ + static int op##name##_w_rmw_a32(uint32_t fetchdat) \ + { \ + uint16_t dst; \ + uint16_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_rm].w = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].w; \ + seteaw(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 1, 0, 1, 0, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_l_rmw_a16(uint32_t fetchdat) \ + { \ + uint32_t dst; \ + uint32_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_rm].l = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].l; \ + seteal(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 1, 0, 1, 0); \ + } \ + return 0; \ + } \ + static int op##name##_l_rmw_a32(uint32_t fetchdat) \ + { \ + uint32_t dst; \ + uint32_t src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod == 3) { \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_rm].l = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); \ + } else { \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + dst = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + src = cpu_state.regs[cpu_reg].l; \ + seteal(operation); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + CLOCK_CYCLES(timing_mr); \ + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 1, 0, 1, 1); \ + } \ + return 0; \ + } \ + \ + static int op##name##_b_rm_a16(uint32_t fetchdat) \ + { \ + uint8_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = getr8(cpu_reg); \ + src = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + setr8(cpu_reg, operation); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_b_rm_a32(uint32_t fetchdat) \ + { \ + uint8_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = getr8(cpu_reg); \ + src = geteab(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##8 flagops; \ + setr8(cpu_reg, operation); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_w_rm_a16(uint32_t fetchdat) \ + { \ + uint16_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].w; \ + src = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_reg].w = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_w_rm_a32(uint32_t fetchdat) \ + { \ + uint16_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].w; \ + src = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##16 flagops; \ + cpu_state.regs[cpu_reg].w = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_l_rm_a16(uint32_t fetchdat) \ + { \ + uint32_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].l; \ + src = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_reg].l = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); \ + return 0; \ + } \ + static int op##name##_l_rm_a32(uint32_t fetchdat) \ + { \ + uint32_t dst, src; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + dst = cpu_state.regs[cpu_reg].l; \ + src = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + setflags##32 flagops; \ + cpu_state.regs[cpu_reg].l = operation; \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); \ + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); \ + return 0; \ + } \ + \ + static int op##name##_AL_imm(uint32_t fetchdat) \ + { \ + uint8_t dst = AL; \ + uint8_t src = getbytef(); \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##8 flagops; \ + AL = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int op##name##_AX_imm(uint32_t fetchdat) \ + { \ + uint16_t dst = AX; \ + uint16_t src = getwordf(); \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##16 flagops; \ + AX = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int op##name##_EAX_imm(uint32_t fetchdat) \ + { \ + uint32_t dst = EAX; \ + uint32_t src = getlong(); \ + if (cpu_state.abrt) \ + return 1; \ + if (gettempc) \ + tempc = CF_SET() ? 1 : 0; \ + setflags##32 flagops; \ + EAX = operation; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } -OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) -OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) -OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) +OP_ARITH(ADD, dst + src, setadd, (dst, src), 0) +OP_ARITH(ADC, dst + src + tempc, setadc, (dst, src), 1) +OP_ARITH(SUB, dst - src, setsub, (dst, src), 0) OP_ARITH(SBB, dst - (src + tempc), setsbc, (dst, src), 1) -OP_ARITH(OR, dst | src, setznp, (dst | src), 0) -OP_ARITH(AND, dst & src, setznp, (dst & src), 0) -OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) +OP_ARITH(OR, dst | src, setznp, (dst | src), 0) +OP_ARITH(AND, dst &src, setznp, (dst & src), 0) +OP_ARITH(XOR, dst ^ src, setznp, (dst ^ src), 0) -static int opCMP_b_rmw_a16(uint32_t fetchdat) +static int +opCMP_b_rmw_a16(uint32_t fetchdat) { - uint8_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(dst, getr8(cpu_reg)); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_b_rmw_a32(uint32_t fetchdat) +static int +opCMP_b_rmw_a32(uint32_t fetchdat) { - uint8_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - setsub8(dst, getr8(cpu_reg)); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(dst, getr8(cpu_reg)); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_w_rmw_a16(uint32_t fetchdat) +static int +opCMP_w_rmw_a16(uint32_t fetchdat) { - uint16_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(dst, cpu_state.regs[cpu_reg].w); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_w_rmw_a32(uint32_t fetchdat) +static int +opCMP_w_rmw_a32(uint32_t fetchdat) { - uint16_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - setsub16(dst, cpu_state.regs[cpu_reg].w); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(dst, cpu_state.regs[cpu_reg].w); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_l_rmw_a16(uint32_t fetchdat) +static int +opCMP_l_rmw_a16(uint32_t fetchdat) { - uint32_t dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(dst, cpu_state.regs[cpu_reg].l); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opCMP_l_rmw_a32(uint32_t fetchdat) +static int +opCMP_l_rmw_a32(uint32_t fetchdat) { - uint32_t dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - setsub32(dst, cpu_state.regs[cpu_reg].l); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(dst, cpu_state.regs[cpu_reg].l); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opCMP_b_rm_a16(uint32_t fetchdat) +static int +opCMP_b_rm_a16(uint32_t fetchdat) { - uint8_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(getr8(cpu_reg), src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_b_rm_a32(uint32_t fetchdat) +static int +opCMP_b_rm_a32(uint32_t fetchdat) { - uint8_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteab(); if (cpu_state.abrt) return 1; - setsub8(getr8(cpu_reg), src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteab(); + if (cpu_state.abrt) + return 1; + setsub8(getr8(cpu_reg), src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_w_rm_a16(uint32_t fetchdat) +static int +opCMP_w_rm_a16(uint32_t fetchdat) { - uint16_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(cpu_state.regs[cpu_reg].w, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opCMP_w_rm_a32(uint32_t fetchdat) +static int +opCMP_w_rm_a32(uint32_t fetchdat) { - uint16_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteaw(); if (cpu_state.abrt) return 1; - setsub16(cpu_state.regs[cpu_reg].w, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteaw(); + if (cpu_state.abrt) + return 1; + setsub16(cpu_state.regs[cpu_reg].w, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opCMP_l_rm_a16(uint32_t fetchdat) +static int +opCMP_l_rm_a16(uint32_t fetchdat) { - uint32_t src; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(cpu_state.regs[cpu_reg].l, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opCMP_l_rm_a32(uint32_t fetchdat) +static int +opCMP_l_rm_a32(uint32_t fetchdat) { - uint32_t src; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - src = geteal(); if (cpu_state.abrt) return 1; - setsub32(cpu_state.regs[cpu_reg].l, src); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + src = geteal(); + if (cpu_state.abrt) + return 1; + setsub32(cpu_state.regs[cpu_reg].l, src); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_rml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opCMP_AL_imm(uint32_t fetchdat) +static int +opCMP_AL_imm(uint32_t fetchdat) { - uint8_t src = getbytef(); - setsub8(AL, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + uint8_t src = getbytef(); + setsub8(AL, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCMP_AX_imm(uint32_t fetchdat) +static int +opCMP_AX_imm(uint32_t fetchdat) { - uint16_t src = getwordf(); - setsub16(AX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + uint16_t src = getwordf(); + setsub16(AX, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCMP_EAX_imm(uint32_t fetchdat) +static int +opCMP_EAX_imm(uint32_t fetchdat) { - uint32_t src = getlong(); if (cpu_state.abrt) return 1; - setsub32(EAX, src); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t src = getlong(); + if (cpu_state.abrt) + return 1; + setsub32(EAX, src); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_b_a16(uint32_t fetchdat) +static int +opTEST_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint8_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opTEST_b_a32(uint32_t fetchdat) +static int +opTEST_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - temp2 = getr8(cpu_reg); - setznp8(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint8_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + temp2 = getr8(cpu_reg); + setznp8(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opTEST_w_a16(uint32_t fetchdat) +static int +opTEST_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 0); - return 0; + uint16_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].w; + setznp16(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opTEST_w_a32(uint32_t fetchdat) +static int +opTEST_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].w; - setznp16(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1,0,0,0, 1); - return 0; + uint16_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].w; + setznp16(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opTEST_l_a16(uint32_t fetchdat) +static int +opTEST_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 0); - return 0; + uint32_t temp, temp2; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].l; + setznp32(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; } -static int opTEST_l_a32(uint32_t fetchdat) +static int +opTEST_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - temp2 = cpu_state.regs[cpu_reg].l; - setznp32(temp & temp2); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0,(cpu_mod == 3) ? 0 : 1,0,0, 1); - return 0; + uint32_t temp, temp2; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + temp2 = cpu_state.regs[cpu_reg].l; + setznp32(temp & temp2); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; } -static int opTEST_AL(uint32_t fetchdat) +static int +opTEST_AL(uint32_t fetchdat) { - uint8_t temp = getbytef(); - setznp8(AL & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + uint8_t temp = getbytef(); + setznp8(AL & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_AX(uint32_t fetchdat) +static int +opTEST_AX(uint32_t fetchdat) { - uint16_t temp = getwordf(); - setznp16(AX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = getwordf(); + setznp16(AX & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opTEST_EAX(uint32_t fetchdat) +static int +opTEST_EAX(uint32_t fetchdat) { - uint32_t temp = getlong(); if (cpu_state.abrt) return 1; - setznp32(EAX & temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = getlong(); + if (cpu_state.abrt) + return 1; + setznp32(EAX & temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } +#define ARITH_MULTI(ea_width, flag_width) \ + dst = getea##ea_width(); \ + if (cpu_state.abrt) \ + return 1; \ + switch (rmdat & 0x38) { \ + case 0x00: /*ADD ea, #*/ \ + setea##ea_width(dst + src); \ + if (cpu_state.abrt) \ + return 1; \ + setadd##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x08: /*OR ea, #*/ \ + dst |= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x10: /*ADC ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ + setea##ea_width(dst + src + tempc); \ + if (cpu_state.abrt) \ + return 1; \ + setadc##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x18: /*SBB ea, #*/ \ + tempc = CF_SET() ? 1 : 0; \ + setea##ea_width(dst - (src + tempc)); \ + if (cpu_state.abrt) \ + return 1; \ + setsbc##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x20: /*AND ea, #*/ \ + dst &= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x28: /*SUB ea, #*/ \ + setea##ea_width(dst - src); \ + if (cpu_state.abrt) \ + return 1; \ + setsub##flag_width(dst, src); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x30: /*XOR ea, #*/ \ + dst ^= src; \ + setea##ea_width(dst); \ + if (cpu_state.abrt) \ + return 1; \ + setznp##flag_width(dst); \ + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ + break; \ + case 0x38: /*CMP ea, #*/ \ + setsub##flag_width(dst, src); \ + if (is486) { \ + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); \ + } else { \ + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); \ + } \ + break; \ + } -#define ARITH_MULTI(ea_width, flag_width) \ - dst = getea ## ea_width(); if (cpu_state.abrt) return 1; \ - switch (rmdat&0x38) \ - { \ - case 0x00: /*ADD ea, #*/ \ - setea ## ea_width(dst + src); if (cpu_state.abrt) return 1; \ - setadd ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x08: /*OR ea, #*/ \ - dst |= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x10: /*ADC ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(dst + src + tempc); if (cpu_state.abrt) return 1; \ - setadc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x18: /*SBB ea, #*/ \ - tempc = CF_SET() ? 1 : 0; \ - setea ## ea_width(dst - (src + tempc)); if (cpu_state.abrt) return 1; \ - setsbc ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x20: /*AND ea, #*/ \ - dst &= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x28: /*SUB ea, #*/ \ - setea ## ea_width(dst - src); if (cpu_state.abrt) return 1; \ - setsub ## flag_width(dst, src); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x30: /*XOR ea, #*/ \ - dst ^= src; \ - setea ## ea_width(dst); if (cpu_state.abrt) return 1; \ - setznp ## flag_width(dst); \ - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mr); \ - break; \ - case 0x38: /*CMP ea, #*/ \ - setsub ## flag_width(dst, src); \ - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } \ - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 7); } \ - break; \ - } - - -static int op80_a16(uint32_t fetchdat) +static int +op80_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(b, 8); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op80_a32(uint32_t fetchdat) +static int +op80_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - ARITH_MULTI(b, 8); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(b, 8); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op81_w_a16(uint32_t fetchdat) +static int +op81_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getword(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op81_w_a32(uint32_t fetchdat) +static int +op81_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getword(); if (cpu_state.abrt) return 1; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getword(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op81_l_a16(uint32_t fetchdat) +static int +op81_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + } - return 0; + return 0; } -static int op81_l_a32(uint32_t fetchdat) +static int +op81_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getlong(); if (cpu_state.abrt) return 1; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getlong(); + if (cpu_state.abrt) + return 1; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 6, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + } - return 0; + return 0; } -static int op83_w_a16(uint32_t fetchdat) +static int +op83_w_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xff00; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + } - return 0; + return 0; } -static int op83_w_a32(uint32_t fetchdat) +static int +op83_w_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xff00; - ARITH_MULTI(w, 16); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xff00; + ARITH_MULTI(w, 16); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + } - return 0; + return 0; } -static int op83_l_a16(uint32_t fetchdat) +static int +op83_l_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xffffff00; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + } - return 0; + return 0; } -static int op83_l_a32(uint32_t fetchdat) +static int +op83_l_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getbyte(); if (cpu_state.abrt) return 1; - if (src & 0x80) src |= 0xffffff00; - ARITH_MULTI(l, 32); - if ((rmdat & 0x38) == 0x38) { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - } else { - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getbyte(); + if (cpu_state.abrt) + return 1; + if (src & 0x80) + src |= 0xffffff00; + ARITH_MULTI(l, 32); + if ((rmdat & 0x38) == 0x38) { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mr, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + } else { + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_rm, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + } - return 0; + return 0; } diff --git a/src/cpu/x86_ops_atomic.h b/src/cpu/x86_ops_atomic.h index 13b672e31..7c7b409d2 100644 --- a/src/cpu/x86_ops_atomic.h +++ b/src/cpu/x86_ops_atomic.h @@ -1,227 +1,295 @@ -static int opCMPXCHG_b_a16(uint32_t fetchdat) +static int +opCMPXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + if (cpu_state.abrt) + return 1; + setsub8(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_b_a32(uint32_t fetchdat) +static int +opCMPXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp, temp2 = AL; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - if (AL == temp) seteab(getr8(cpu_reg)); - else AL = temp; - if (cpu_state.abrt) return 1; - setsub8(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint8_t temp, temp2 = AL; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + if (AL == temp) + seteab(getr8(cpu_reg)); + else + AL = temp; + if (cpu_state.abrt) + return 1; + setsub8(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_w_a16(uint32_t fetchdat) +static int +opCMPXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + if (cpu_state.abrt) + return 1; + setsub16(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_w_a32(uint32_t fetchdat) +static int +opCMPXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp, temp2 = AX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - if (AX == temp) seteaw(cpu_state.regs[cpu_reg].w); - else AX = temp; - if (cpu_state.abrt) return 1; - setsub16(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint16_t temp, temp2 = AX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (AX == temp) + seteaw(cpu_state.regs[cpu_reg].w); + else + AX = temp; + if (cpu_state.abrt) + return 1; + setsub16(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_l_a16(uint32_t fetchdat) +static int +opCMPXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + if (cpu_state.abrt) + return 1; + setsub32(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG_l_a32(uint32_t fetchdat) +static int +opCMPXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp, temp2 = EAX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - if (EAX == temp) seteal(cpu_state.regs[cpu_reg].l); - else EAX = temp; - if (cpu_state.abrt) return 1; - setsub32(temp2, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); - return 0; + uint32_t temp, temp2 = EAX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (EAX == temp) + seteal(cpu_state.regs[cpu_reg].l); + else + EAX = temp; + if (cpu_state.abrt) + return 1; + setsub32(temp2, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 6 : 10); + return 0; } -static int opCMPXCHG8B_a16(uint32_t fetchdat) +static int +opCMPXCHG8B_a16(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; + uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 0; + if (EAX == temp && EDX == temp_hi) { + seteal(EBX); + writememl(easeg, cpu_state.eaaddr + 4, ECX); + } else { + EAX = temp; + EDX = temp_hi; + } + if (cpu_state.abrt) + return 0; + flags_rebuild(); + if (temp == temp2 && temp_hi == temp2_hi) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; + return 0; } -static int opCMPXCHG8B_a32(uint32_t fetchdat) +static int +opCMPXCHG8B_a32(uint32_t fetchdat) { - uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - if (EAX == temp && EDX == temp_hi) - { - seteal(EBX); - writememl(easeg, cpu_state.eaaddr+4, ECX); - } - else - { - EAX = temp; - EDX = temp_hi; - } - if (cpu_state.abrt) return 0; - flags_rebuild(); - if (temp == temp2 && temp_hi == temp2_hi) - cpu_state.flags |= Z_FLAG; - else - cpu_state.flags &= ~Z_FLAG; - cycles -= (cpu_mod == 3) ? 6 : 10; + uint32_t temp, temp_hi, temp2 = EAX, temp2_hi = EDX; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + temp_hi = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 0; + if (EAX == temp && EDX == temp_hi) { + seteal(EBX); + writememl(easeg, cpu_state.eaaddr + 4, ECX); + } else { + EAX = temp; + EDX = temp_hi; + } + if (cpu_state.abrt) + return 0; + flags_rebuild(); + if (temp == temp2 && temp_hi == temp2_hi) + cpu_state.flags |= Z_FLAG; + else + cpu_state.flags &= ~Z_FLAG; + cycles -= (cpu_mod == 3) ? 6 : 10; + return 0; } /* dest = eab, src = r8 */ -static int opXADD_b_a16(uint32_t fetchdat) +static int +opXADD_b_a16(uint32_t fetchdat) { - uint8_t temp; - uint8_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getr8(cpu_reg); - dest = geteab(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteab(temp); if (cpu_state.abrt) return 1; - setadd8(src, dest); - setr8(cpu_reg, dest); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + uint8_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getr8(cpu_reg); + dest = geteab(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteab(temp); + if (cpu_state.abrt) + return 1; + setadd8(src, dest); + setr8(cpu_reg, dest); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_b_a32(uint32_t fetchdat) +static int +opXADD_b_a32(uint32_t fetchdat) { - uint8_t temp; - uint8_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = getr8(cpu_reg); - dest = geteab(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteab(temp); if (cpu_state.abrt) return 1; - setadd8(src, dest); - setr8(cpu_reg, dest); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint8_t temp; + uint8_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = getr8(cpu_reg); + dest = geteab(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteab(temp); + if (cpu_state.abrt) + return 1; + setadd8(src, dest); + setr8(cpu_reg, dest); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_w_a16(uint32_t fetchdat) +static int +opXADD_w_a16(uint32_t fetchdat) { - uint16_t temp; - uint16_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].w; - dest = geteaw(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteaw(temp); if (cpu_state.abrt) return 1; - setadd16(src, dest); - cpu_state.regs[cpu_reg].w = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + uint16_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].w; + dest = geteaw(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteaw(temp); + if (cpu_state.abrt) + return 1; + setadd16(src, dest); + cpu_state.regs[cpu_reg].w = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_w_a32(uint32_t fetchdat) +static int +opXADD_w_a32(uint32_t fetchdat) { - uint16_t temp; - uint16_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].w; - dest = geteaw(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteaw(temp); if (cpu_state.abrt) return 1; - setadd16(src, dest); - cpu_state.regs[cpu_reg].w = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint16_t temp; + uint16_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].w; + dest = geteaw(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteaw(temp); + if (cpu_state.abrt) + return 1; + setadd16(src, dest); + cpu_state.regs[cpu_reg].w = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_l_a16(uint32_t fetchdat) +static int +opXADD_l_a16(uint32_t fetchdat) { - uint32_t temp; - uint32_t src, dest; - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].l; - dest = geteal(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteal(temp); if (cpu_state.abrt) return 1; - setadd32(src, dest); - cpu_state.regs[cpu_reg].l = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + uint32_t src, dest; + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].l; + dest = geteal(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteal(temp); + if (cpu_state.abrt) + return 1; + setadd32(src, dest); + cpu_state.regs[cpu_reg].l = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } -static int opXADD_l_a32(uint32_t fetchdat) +static int +opXADD_l_a32(uint32_t fetchdat) { - uint32_t temp; - uint32_t src, dest; - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - src = cpu_state.regs[cpu_reg].l; - dest = geteal(); if (cpu_state.abrt) return 1; - temp = src + dest; - seteal(temp); if (cpu_state.abrt) return 1; - setadd32(src, dest); - cpu_state.regs[cpu_reg].l = dest; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); - return 0; + uint32_t temp; + uint32_t src, dest; + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + src = cpu_state.regs[cpu_reg].l; + dest = geteal(); + if (cpu_state.abrt) + return 1; + temp = src + dest; + seteal(temp); + if (cpu_state.abrt) + return 1; + setadd32(src, dest); + cpu_state.regs[cpu_reg].l = dest; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 4); + return 0; } diff --git a/src/cpu/x86_ops_bcd.h b/src/cpu/x86_ops_bcd.h index 385d63cd7..d3ff97ead 100644 --- a/src/cpu/x86_ops_bcd.h +++ b/src/cpu/x86_ops_bcd.h @@ -1,129 +1,130 @@ -static int opAAA(uint32_t fetchdat) +static int +opAAA(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) - { - /* On 286, it's indeed AX - behavior difference from 808x. */ - AX += 6; - AH++; - cpu_state.flags |= (A_FLAG | C_FLAG); - } - else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX += 6; + AH++; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + CLOCK_CYCLES(is486 ? 3 : 4); + PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAD(uint32_t fetchdat) +static int +opAAD(uint32_t fetchdat) { - int base = getbytef(); - if (!cpu_isintel) base = 10; - AL = (AH * base) + AL; - AH = 0; - setznp16(AX); - CLOCK_CYCLES((is486) ? 14 : 19); - PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0,0,0,0, 0); - return 0; + int base = getbytef(); + if (!cpu_isintel) + base = 10; + AL = (AH * base) + AL; + AH = 0; + setznp16(AX); + CLOCK_CYCLES((is486) ? 14 : 19); + PREFETCH_RUN(is486 ? 14 : 19, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAM(uint32_t fetchdat) +static int +opAAM(uint32_t fetchdat) { - int base = getbytef(); - if (!base || !cpu_isintel) base = 10; - AH = AL / base; - AL %= base; - setznp16(AX); - CLOCK_CYCLES((is486) ? 15 : 17); - PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0,0,0,0, 0); - return 0; + int base = getbytef(); + if (!base || !cpu_isintel) + base = 10; + AH = AL / base; + AL %= base; + setznp16(AX); + CLOCK_CYCLES((is486) ? 15 : 17); + PREFETCH_RUN(is486 ? 15 : 17, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opAAS(uint32_t fetchdat) +static int +opAAS(uint32_t fetchdat) { - flags_rebuild(); - if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) - { - /* On 286, it's indeed AX - behavior difference from 808x. */ - AX -= 6; - AH--; - cpu_state.flags |= (A_FLAG | C_FLAG); - } - else - cpu_state.flags &= ~(A_FLAG | C_FLAG); - AL &= 0xF; - CLOCK_CYCLES(is486 ? 3 : 4); - PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + if ((cpu_state.flags & A_FLAG) || ((AL & 0xF) > 9)) { + /* On 286, it's indeed AX - behavior difference from 808x. */ + AX -= 6; + AH--; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else + cpu_state.flags &= ~(A_FLAG | C_FLAG); + AL &= 0xF; + CLOCK_CYCLES(is486 ? 3 : 4); + PREFETCH_RUN(is486 ? 3 : 4, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opDAA(uint32_t fetchdat) +static int +opDAA(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw, old_AL, old_CF; - flags_rebuild(); - old_AL = AL; - old_CF = cpu_state.flags & C_FLAG; - cpu_state.flags &= ~C_FLAG; + flags_rebuild(); + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; - if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { - int tempi = ((uint16_t)AL) + 6; - AL += 6; - if (old_CF || (tempi & 0x100)) - cpu_state.flags |= C_FLAG; - cpu_state.flags |= A_FLAG; - } else - cpu_state.flags &= ~A_FLAG; + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { + int tempi = ((uint16_t) AL) + 6; + AL += 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; - if ((old_AL > 0x99) || old_CF) - { - AL += 0x60; - cpu_state.flags |= C_FLAG; - } else - cpu_state.flags &= ~C_FLAG; + if ((old_AL > 0x99) || old_CF) { + AL += 0x60; + cpu_state.flags |= C_FLAG; + } else + cpu_state.flags &= ~C_FLAG; - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } -static int opDAS(uint32_t fetchdat) +static int +opDAS(uint32_t fetchdat) { - uint16_t tempw, old_AL, old_CF; + uint16_t tempw, old_AL, old_CF; - flags_rebuild(); - old_AL = AL; - old_CF = cpu_state.flags & C_FLAG; - cpu_state.flags &= ~C_FLAG; + flags_rebuild(); + old_AL = AL; + old_CF = cpu_state.flags & C_FLAG; + cpu_state.flags &= ~C_FLAG; - if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) - { - int tempi = ((uint16_t)AL) - 6; - AL -= 6; - if (old_CF || (tempi & 0x100)) - cpu_state.flags |= C_FLAG; - cpu_state.flags |= A_FLAG; - } else - cpu_state.flags &= ~A_FLAG; + if (((AL & 0xf) > 9) || (cpu_state.flags & A_FLAG)) { + int tempi = ((uint16_t) AL) - 6; + AL -= 6; + if (old_CF || (tempi & 0x100)) + cpu_state.flags |= C_FLAG; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; - if ((old_AL > 0x99) || old_CF) - { - AL -= 0x60; - cpu_state.flags |= C_FLAG; - } + if ((old_AL > 0x99) || old_CF) { + AL -= 0x60; + cpu_state.flags |= C_FLAG; + } - tempw = cpu_state.flags & (C_FLAG | A_FLAG); - setznp8(AL); - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,0, 0); + tempw = cpu_state.flags & (C_FLAG | A_FLAG); + setznp8(AL); + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & ~(C_FLAG | A_FLAG)) | tempw; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 0, 0); - return 0; + return 0; } diff --git a/src/cpu/x86_ops_bit.h b/src/cpu/x86_ops_bit.h index 4fc8ac0f7..8514e8e1c 100644 --- a/src/cpu/x86_ops_bit.h +++ b/src/cpu/x86_ops_bit.h @@ -1,328 +1,411 @@ -static int opBT_w_r_a16(uint32_t fetchdat) +static int +opBT_w_r_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opBT_w_r_a32(uint32_t fetchdat) +static int +opBT_w_r_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = 0; - temp = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); + eal_r = 0; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opBT_l_r_a16(uint32_t fetchdat) +static int +opBT_l_r_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opBT_l_r_a32(uint32_t fetchdat) +static int +opBT_l_r_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = 0; - temp = geteal(); if (cpu_state.abrt) return 1; - flags_rebuild(); - if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); + eal_r = 0; + temp = geteal(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + if (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } -#define opBT(name, operation) \ - static int opBT ## name ## _w_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 0); \ - return 0; \ - } \ - static int opBT ## name ## _w_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint16_t temp; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); eal_r = eal_w = 0; \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].w & 15)); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 1,0,1,0, 1); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a16(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 0); \ - return 0; \ - } \ - static int opBT ## name ## _l_r_a32(uint32_t fetchdat) \ - { \ - int tempc; \ - uint32_t temp; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); eal_r = eal_w = 0; \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ - temp operation (1 << (cpu_state.regs[cpu_reg].l & 31)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - else cpu_state.flags &= ~C_FLAG; \ - \ - CLOCK_CYCLES(6); \ - PREFETCH_RUN(6, 2, rmdat, 0,1,0,1, 1); \ - return 0; \ - } +#define opBT(name, operation) \ + static int opBT##name##_w_r_a16(uint32_t fetchdat) \ + { \ + int tempc; \ + uint16_t temp; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \ + eal_r = eal_w = 0; \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 0); \ + return 0; \ + } \ + static int opBT##name##_w_r_a32(uint32_t fetchdat) \ + { \ + int tempc; \ + uint16_t temp; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].w / 16) * 2); \ + eal_r = eal_w = 0; \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].w & 15))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].w & 15)); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 1, 0, 1, 0, 1); \ + return 0; \ + } \ + static int opBT##name##_l_r_a16(uint32_t fetchdat) \ + { \ + int tempc; \ + uint32_t temp; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \ + eal_r = eal_w = 0; \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 0); \ + return 0; \ + } \ + static int opBT##name##_l_r_a32(uint32_t fetchdat) \ + { \ + int tempc; \ + uint32_t temp; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + cpu_state.eaaddr += ((cpu_state.regs[cpu_reg].l / 32) * 4); \ + eal_r = eal_w = 0; \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (temp & (1 << (cpu_state.regs[cpu_reg].l & 31))) ? 1 : 0; \ + temp operation(1 << (cpu_state.regs[cpu_reg].l & 31)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + else \ + cpu_state.flags &= ~C_FLAG; \ + \ + CLOCK_CYCLES(6); \ + PREFETCH_RUN(6, 2, rmdat, 0, 1, 0, 1, 1); \ + return 0; \ + } opBT(C, ^=) -opBT(R, &=~) -opBT(S, |=) + opBT(R, &= ~) + opBT(S, |=) -static int opBA_w_a16(uint32_t fetchdat) + static int opBA_w_a16(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + int tempc, count; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteaw(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteaw(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opBA_w_a32(uint32_t fetchdat) +static int +opBA_w_a32(uint32_t fetchdat) { - int tempc, count; - uint16_t temp; + int tempc, count; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteaw(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteaw(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteaw(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opBA_l_a16(uint32_t fetchdat) +static int +opBA_l_a16(uint32_t fetchdat) { - int tempc, count; - uint32_t temp; + int tempc, count; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteal(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteal(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return 0; } -static int opBA_l_a32(uint32_t fetchdat) +static int +opBA_l_a32(uint32_t fetchdat) { - int tempc, count; - uint32_t temp; + int tempc, count; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); - count = getbyte(); if (cpu_state.abrt) return 1; - tempc = temp & (1 << count); - flags_rebuild(); - switch (rmdat & 0x38) - { - case 0x20: /*BT w,imm*/ - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return 0; - case 0x28: /*BTS w,imm*/ - temp |= (1 << count); - break; - case 0x30: /*BTR w,imm*/ - temp &= ~(1 << count); - break; - case 0x38: /*BTC w,imm*/ - temp ^= (1 << count); - break; + temp = geteal(); + count = getbyte(); + if (cpu_state.abrt) + return 1; + tempc = temp & (1 << count); + flags_rebuild(); + switch (rmdat & 0x38) { + case 0x20: /*BT w,imm*/ + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return 0; + case 0x28: /*BTS w,imm*/ + temp |= (1 << count); + break; + case 0x30: /*BTR w,imm*/ + temp &= ~(1 << count); + break; + case 0x38: /*BTC w,imm*/ + temp ^= (1 << count); + break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - seteal(temp); if (cpu_state.abrt) return 1; - if (tempc) cpu_state.flags |= C_FLAG; - else cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + seteal(temp); + if (cpu_state.abrt) + return 1; + if (tempc) + cpu_state.flags |= C_FLAG; + else + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return 0; } diff --git a/src/cpu/x86_ops_bitscan.h b/src/cpu/x86_ops_bitscan.h index af87a545d..358131c1e 100644 --- a/src/cpu/x86_ops_bitscan.h +++ b/src/cpu/x86_ops_bitscan.h @@ -1,211 +1,227 @@ #ifdef IS_DYNAREC -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - cpu_state.flags |= Z_FLAG; +# define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ + cpu_state.flags |= Z_FLAG; #else -#define BS_common(start, end, dir, dest, time) \ - flags_rebuild(); \ - instr_cycles = 0; \ - if (temp) \ - { \ - int c; \ - cpu_state.flags &= ~Z_FLAG; \ - for (c = start; c != end; c += dir) \ - { \ - CLOCK_CYCLES(time); \ - instr_cycles += time; \ - if (temp & (1 << c)) \ - { \ - dest = c; \ - break; \ - } \ - } \ - } \ - else \ - cpu_state.flags |= Z_FLAG; +# define BS_common(start, end, dir, dest, time) \ + flags_rebuild(); \ + instr_cycles = 0; \ + if (temp) { \ + int c; \ + cpu_state.flags &= ~Z_FLAG; \ + for (c = start; c != end; c += dir) { \ + CLOCK_CYCLES(time); \ + instr_cycles += time; \ + if (temp & (1 << c)) { \ + dest = c; \ + break; \ + } \ + } \ + } else \ + cpu_state.flags |= Z_FLAG; #endif -static int opBSF_w_a16(uint32_t fetchdat) +static int +opBSF_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSF_w_a32(uint32_t fetchdat) +static int +opBSF_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); + BS_common(0, 16, 1, cpu_state.regs[cpu_reg].w, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSF_l_a16(uint32_t fetchdat) +static int +opBSF_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSF_l_a32(uint32_t fetchdat) +static int +opBSF_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); + BS_common(0, 32, 1, cpu_state.regs[cpu_reg].l, (is486) ? 1 : 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSR_w_a16(uint32_t fetchdat) +static int +opBSR_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSR_w_a32(uint32_t fetchdat) +static int +opBSR_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; - BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); + BS_common(15, -1, -1, cpu_state.regs[cpu_reg].w, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); #endif - return 0; + return 0; } -static int opBSR_l_a16(uint32_t fetchdat) +static int +opBSR_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); #endif - return 0; + return 0; } -static int opBSR_l_a32(uint32_t fetchdat) +static int +opBSR_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; #ifndef IS_DYNAREC - int instr_cycles = 0; + int instr_cycles = 0; #endif - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; - BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); + BS_common(31, -1, -1, cpu_state.regs[cpu_reg].l, 3); - CLOCK_CYCLES((is486) ? 6 : 10); + CLOCK_CYCLES((is486) ? 6 : 10); #ifndef IS_DYNAREC - instr_cycles += ((is486) ? 6 : 10); - PREFETCH_RUN(instr_cycles, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); + instr_cycles += ((is486) ? 6 : 10); + PREFETCH_RUN(instr_cycles, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); #endif - return 0; + return 0; } diff --git a/src/cpu/x86_ops_call.h b/src/cpu/x86_ops_call.h index ecd50f107..88899cef8 100644 --- a/src/cpu/x86_ops_call.h +++ b/src/cpu/x86_ops_call.h @@ -1,627 +1,879 @@ #ifdef USE_NEW_DYNAREC -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +# define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate32) { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg, old_pc); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { CS = old_cs; cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { CS = old_cs; ESP = old_esp; return 1; } \ +# define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg, old_pc); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate16) { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + CS = old_cs; \ + ESP = old_esp; \ + return 1; \ + } \ } #else -#define CALL_FAR_w(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate32) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ +# define CALL_FAR_w(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate32) { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ } -#define CALL_FAR_l(new_seg, new_pc) \ - old_cs = CS; \ - old_pc = cpu_state.pc; \ - oxpc = cpu_state.pc; \ - cpu_state.pc = new_pc; \ - optype = CALL; \ - cgate16 = cgate32 = 0; \ - if (msw & 1) loadcscall(new_seg); \ - else \ - { \ - loadcs(new_seg); \ - cycles -= timing_call_rm; \ - } \ - optype = 0; \ - if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - oldss = ss; \ - if (cgate16) \ - { \ - uint32_t old_esp = ESP; \ - PUSH_W(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_W(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ - } \ - else \ - { \ - uint32_t old_esp = ESP; \ - PUSH_L(old_cs); if (cpu_state.abrt) { cgate16 = cgate32 = 0; return 1; } \ - PUSH_L(old_pc); if (cpu_state.abrt) { ESP = old_esp; return 1; } \ +# define CALL_FAR_l(new_seg, new_pc) \ + old_cs = CS; \ + old_pc = cpu_state.pc; \ + oxpc = cpu_state.pc; \ + cpu_state.pc = new_pc; \ + optype = CALL; \ + cgate16 = cgate32 = 0; \ + if (msw & 1) \ + loadcscall(new_seg); \ + else { \ + loadcs(new_seg); \ + cycles -= timing_call_rm; \ + } \ + optype = 0; \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + oldss = ss; \ + if (cgate16) { \ + uint32_t old_esp = ESP; \ + PUSH_W(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_W(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ + } else { \ + uint32_t old_esp = ESP; \ + PUSH_L(old_cs); \ + if (cpu_state.abrt) { \ + cgate16 = cgate32 = 0; \ + return 1; \ + } \ + PUSH_L(old_pc); \ + if (cpu_state.abrt) { \ + ESP = old_esp; \ + return 1; \ + } \ } #endif - -static int opCALL_far_w(uint32_t fetchdat) +static int +opCALL_far_w(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint16_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint32_t old_cs, old_pc; + uint16_t new_cs, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - new_pc = getwordf(); - new_cs = getword(); if (cpu_state.abrt) return 1; + new_pc = getwordf(); + new_cs = getword(); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 5, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 5, -1, 0, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); - return 0; + return 0; } -static int opCALL_far_l(uint32_t fetchdat) +static int +opCALL_far_l(uint32_t fetchdat) { - uint32_t old_cs, old_pc; - uint32_t new_cs, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint32_t old_cs, old_pc; + uint32_t new_cs, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - new_pc = getlong(); - new_cs = getword(); if (cpu_state.abrt) return 1; + new_pc = getlong(); + new_cs = getword(); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 7, -1, 0,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 7, -1, 0, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); - return 0; + return 0; } - -static int opFF_w_a16(uint32_t fetchdat) +static int +opFF_w_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x08: /*DEC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp + 1); + if (cpu_state.abrt) + return 1; + setadd16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x08: /*DEC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp - 1); + if (cpu_state.abrt) + return 1; + setsub16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 0); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 0); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_w_a32(uint32_t fetchdat) +static int +opFF_w_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp + 1); if (cpu_state.abrt) return 1; - setadd16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x08: /*DEC w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - seteaw(temp - 1); if (cpu_state.abrt) return 1; - setsub16nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp + 1); + if (cpu_state.abrt) + return 1; + setadd16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x08: /*DEC w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + seteaw(temp - 1); + if (cpu_state.abrt) + return 1; + setsub16nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 2)); + if (cpu_state.abrt) + return 1; - CALL_FAR_w(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - new_pc = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } + CALL_FAR_w(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 1); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + new_pc = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 0, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmemw(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmemw(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 2,0,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH w*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); - } - temp = geteaw(); if (cpu_state.abrt) return 1; - PUSH_W(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,1,0, 1); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 2, 0, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH w*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1UL); + } + temp = geteaw(); + if (cpu_state.abrt) + return 1; + PUSH_W(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 1, 0, 1); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_l_a16(uint32_t fetchdat) +static int +opFF_l_a16(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x08: /*DEC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp + 1); + if (cpu_state.abrt) + return 1; + setadd32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x08: /*DEC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp - 1); + if (cpu_state.abrt) + return 1; + setsub32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 0); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 0); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 0,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 0); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 0); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 0); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 0); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(temp); + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 0); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } -static int opFF_l_a32(uint32_t fetchdat) +static int +opFF_l_a32(uint32_t fetchdat) { - uint16_t old_cs, new_cs; - uint32_t old_pc, new_pc; - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t old_cs, new_cs; + uint32_t old_pc, new_pc; + int cycles_old = cycles; + UN_USED(cycles_old); - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - switch (rmdat & 0x38) - { - case 0x00: /*INC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp + 1); if (cpu_state.abrt) return 1; - setadd32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x08: /*DEC l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - if (cpu_mod != 3) { - CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - seteal(temp - 1); if (cpu_state.abrt) return 1; - setsub32nc(temp, 1); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x10: /*CALL*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - PREFETCH_FLUSH(); - break; - case 0x18: /*CALL far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); if (cpu_state.abrt) return 1; + switch (rmdat & 0x38) { + case 0x00: /*INC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp + 1); + if (cpu_state.abrt) + return 1; + setadd32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x08: /*DEC l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + if (cpu_mod != 3) { + CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + seteal(temp - 1); + if (cpu_state.abrt) + return 1; + setsub32nc(temp, 1); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x10: /*CALL*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN((cpu_mod == 3) ? 7 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 1); + PREFETCH_FLUSH(); + break; + case 0x18: /*CALL far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, (cpu_state.eaaddr + 4)); + if (cpu_state.abrt) + return 1; - CALL_FAR_l(new_cs, new_pc); - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,cgate16 ? 2:0,cgate16 ? 0:2, 1); - PREFETCH_FLUSH(); - break; - case 0x20: /*JMP*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - new_pc = geteal(); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; - CPU_BLOCK_END(); - if (is486) { CLOCK_CYCLES(5); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); } - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x28: /*JMP far*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); - } + CALL_FAR_l(new_cs, new_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, cgate16 ? 2 : 0, cgate16 ? 0 : 2, 1); + PREFETCH_FLUSH(); + break; + case 0x20: /*JMP*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + new_pc = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; + CPU_BLOCK_END(); + if (is486) { + CLOCK_CYCLES(5); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 7 : 10); + } + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x28: /*JMP far*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5UL); + } #ifdef USE_NEW_DYNAREC - old_pc = cpu_state.pc; + old_pc = cpu_state.pc; #else - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - new_pc = readmeml(easeg, cpu_state.eaaddr); - new_cs = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - cpu_state.pc = new_pc; + new_pc = readmeml(easeg, cpu_state.eaaddr); + new_cs = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + cpu_state.pc = new_pc; #ifdef USE_NEW_DYNAREC - loadcsjmp(new_cs, old_pc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, old_pc); + if (cpu_state.abrt) + return 1; #else - loadcsjmp(new_cs, oxpc); if (cpu_state.abrt) return 1; + loadcsjmp(new_cs, oxpc); + if (cpu_state.abrt) + return 1; #endif - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 2, rmdat, 1,1,0,0, 1); - PREFETCH_FLUSH(); - break; - case 0x30: /*PUSH l*/ - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); if (cpu_state.abrt) return 1; - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); - } - temp = geteal(); if (cpu_state.abrt) return 1; - PUSH_L(temp); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,1, 1); - break; + CPU_BLOCK_END(); + PREFETCH_RUN(cycles_old - cycles, 2, rmdat, 1, 1, 0, 0, 1); + PREFETCH_FLUSH(); + break; + case 0x30: /*PUSH l*/ + if (cpu_mod != 3) { + SEG_CHECK_READ(cpu_state.ea_seg); + if (cpu_state.abrt) + return 1; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3UL); + } + temp = geteal(); + if (cpu_state.abrt) + return 1; + PUSH_L(temp); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 1, 1); + break; - default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); - x86illegal(); - } - return cpu_state.abrt; + default: + // fatal("Bad FF opcode %02X\n",rmdat&0x38); + x86illegal(); + } + return cpu_state.abrt; } diff --git a/src/cpu/x86_ops_cyrix.h b/src/cpu/x86_ops_cyrix.h index 500b119fb..672ebd08e 100644 --- a/src/cpu/x86_ops_cyrix.h +++ b/src/cpu/x86_ops_cyrix.h @@ -1,272 +1,265 @@ /*Cyrix-only instructions*/ /*System Management Mode*/ -static void opSVDC_common(uint32_t fetchdat) +static void +opSVDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); - writememw(0, easeg+cpu_state.eaaddr+8, ES); - break; - case 0x08: /*CS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_cs); - writememw(0, easeg+cpu_state.eaaddr+8, CS); - break; - case 0x18: /*DS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); - writememw(0, easeg+cpu_state.eaaddr+8, DS); - break; - case 0x10: /*SS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); - writememw(0, easeg+cpu_state.eaaddr+8, SS); - break; - case 0x20: /*FS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); - writememw(0, easeg+cpu_state.eaaddr+8, FS); - break; - case 0x28: /*GS*/ - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); - writememw(0, easeg+cpu_state.eaaddr+8, GS); - break; - default: - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + writememw(0, easeg + cpu_state.eaaddr + 8, ES); + break; + case 0x08: /*CS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_cs); + writememw(0, easeg + cpu_state.eaaddr + 8, CS); + break; + case 0x18: /*DS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + writememw(0, easeg + cpu_state.eaaddr + 8, DS); + break; + case 0x10: /*SS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + writememw(0, easeg + cpu_state.eaaddr + 8, SS); + break; + case 0x20: /*FS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + writememw(0, easeg + cpu_state.eaaddr + 8, FS); + break; + case 0x28: /*GS*/ + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + writememw(0, easeg + cpu_state.eaaddr + 8, GS); + break; + default: + x86illegal(); + } } -static int opSVDC_a16(uint32_t fetchdat) +static int +opSVDC_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVDC_a32(uint32_t fetchdat) +static int +opSVDC_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - opSVDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + opSVDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static void opRSDC_common(uint32_t fetchdat) +static void +opRSDC_common(uint32_t fetchdat) { - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_ss); - break; - case 0x20: /*FS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &cpu_state.seg_gs); - break; - default: - x86illegal(); - } + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_ss); + break; + case 0x20: /*FS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &cpu_state.seg_gs); + break; + default: + x86illegal(); + } } -static int opRSDC_a16(uint32_t fetchdat) +static int +opRSDC_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSDC_a32(uint32_t fetchdat) +static int +opRSDC_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - opRSDC_common(fetchdat); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + opRSDC_common(fetchdat); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVLDT_a16(uint32_t fetchdat) +static int +opSVLDT_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVLDT_a32(uint32_t fetchdat) +static int +opSVLDT_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - writememw(0, easeg+cpu_state.eaaddr+8, ldt.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + writememw(0, easeg + cpu_state.eaaddr + 8, ldt.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSLDT_a16(uint32_t fetchdat) +static int +opRSLDT_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSLDT_a32(uint32_t fetchdat) +static int +opRSLDT_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - cyrix_load_seg_descriptor(easeg+cpu_state.eaaddr, &ldt); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + cyrix_load_seg_descriptor(easeg + cpu_state.eaaddr, &ldt); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVTS_a16(uint32_t fetchdat) +static int +opSVTS_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSVTS_a32(uint32_t fetchdat) +static int +opSVTS_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSTS_a16(uint32_t fetchdat) +static int +opRSTS_a16(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opRSTS_a32(uint32_t fetchdat) +static int +opRSTS_a32(uint32_t fetchdat) { - if (in_smm) - { - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - cyrix_write_seg_descriptor(easeg+cpu_state.eaaddr, &tr); - writememw(0, easeg+cpu_state.eaaddr+8, tr.seg); - } - else - x86illegal(); + if (in_smm) { + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + cyrix_write_seg_descriptor(easeg + cpu_state.eaaddr, &tr); + writememw(0, easeg + cpu_state.eaaddr + 8, tr.seg); + } else + x86illegal(); - return cpu_state.abrt; + return cpu_state.abrt; } -static int opSMINT(uint32_t fetchdat) +static int +opSMINT(uint32_t fetchdat) { - if (in_smm) - fatal("opSMINT\n"); - else - x86illegal(); + if (in_smm) + fatal("opSMINT\n"); + else + x86illegal(); - return 1; + return 1; } -static int opRDSHR_a16(uint32_t fetchdat) +static int +opRDSHR_a16(uint32_t fetchdat) { - if (in_smm) - fatal("opRDSHR_a16\n"); - else - x86illegal(); + if (in_smm) + fatal("opRDSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } -static int opRDSHR_a32(uint32_t fetchdat) +static int +opRDSHR_a32(uint32_t fetchdat) { - if (in_smm) - fatal("opRDSHR_a32\n"); - else - x86illegal(); + if (in_smm) + fatal("opRDSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } -static int opWRSHR_a16(uint32_t fetchdat) +static int +opWRSHR_a16(uint32_t fetchdat) { - if (in_smm) - fatal("opWRSHR_a16\n"); - else - x86illegal(); + if (in_smm) + fatal("opWRSHR_a16\n"); + else + x86illegal(); - return 1; + return 1; } -static int opWRSHR_a32(uint32_t fetchdat) +static int +opWRSHR_a32(uint32_t fetchdat) { - if (in_smm) - fatal("opWRSHR_a32\n"); - else - x86illegal(); + if (in_smm) + fatal("opWRSHR_a32\n"); + else + x86illegal(); - return 1; + return 1; } diff --git a/src/cpu/x86_ops_flag.h b/src/cpu/x86_ops_flag.h index 16215b525..f08b30fce 100644 --- a/src/cpu/x86_ops_flag.h +++ b/src/cpu/x86_ops_flag.h @@ -1,313 +1,319 @@ -static int opCMC(uint32_t fetchdat) +static int +opCMC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags ^= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + cpu_state.flags ^= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } - -static int opCLC(uint32_t fetchdat) +static int +opCLC(uint32_t fetchdat) { - flags_rebuild(); - cpu_state.flags &= ~C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + flags_rebuild(); + cpu_state.flags &= ~C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCLD(uint32_t fetchdat) +static int +opCLD(uint32_t fetchdat) { - cpu_state.flags &= ~D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + cpu_state.flags &= ~D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCLI(uint32_t fetchdat) +static int +opCLI(uint32_t fetchdat) { - if (!IOPLp) - { - if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - cpu_state.eflags &= ~VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + cpu_state.eflags &= ~VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; } + } else + cpu_state.flags &= ~I_FLAG; + + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSTC(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTD(uint32_t fetchdat) +{ + cpu_state.flags |= D_FLAG; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opSTI(uint32_t fetchdat) +{ + if (!IOPLp) { + if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) { + if (cpu_state.eflags & VIP_FLAG) { + x86gpf(NULL, 0); + return 1; + } else + cpu_state.eflags |= VIF_FLAG; + } else { + x86gpf(NULL, 0); + return 1; + } + } else + cpu_state.flags |= I_FLAG; + + /*First instruction after STI will always execute, regardless of whether + there is a pending interrupt*/ + cpu_end_block_after_ins = 2; + + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opSAHF(uint32_t fetchdat) +{ + flags_rebuild(); + cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opLAHF(uint32_t fetchdat) +{ + flags_rebuild(); + AH = cpu_state.flags & 0xff; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opPUSHF(uint32_t fetchdat) +{ + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint16_t temp; + + flags_rebuild(); + temp = (cpu_state.flags & ~I_FLAG) | 0x3000; + if (cpu_state.eflags & VIF_FLAG) + temp |= I_FLAG; + PUSH_W(temp); + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + flags_rebuild(); + PUSH_W(cpu_state.flags); + } + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opPUSHFD(uint32_t fetchdat) +{ + uint16_t tempw; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_CR4_mask & CR4_VME) + tempw = cpu_state.eflags & 0x3c; + else if (CPUID) + tempw = cpu_state.eflags & 0x24; + else + tempw = cpu_state.eflags & 4; + flags_rebuild(); + PUSH_L(cpu_state.flags | (tempw << 16)); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} + +static int +opPOPF_186(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF_286(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } + + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(msw & 1)) + cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; + else if (!(CPL)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + flags_extract(); + + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + +#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) + codegen_flags_changed = 0; +#endif + + return 0; +} +static int +opPOPF(uint32_t fetchdat) +{ + uint16_t tempw; + + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + if (cr4 & CR4_VME) { + uint32_t old_esp = ESP; + + tempw = POP_W(); + if (cpu_state.abrt) { + + ESP = old_esp; + return 1; + } + + if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + ESP = old_esp; + x86gpf(NULL, 0); + return 1; + } + if (tempw & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } else { + x86gpf(NULL, 0); + return 1; + } + } else { + tempw = POP_W(); + if (cpu_state.abrt) + return 1; + + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (tempw & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; else - cpu_state.flags &= ~I_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; + } + flags_extract(); - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSTC(uint32_t fetchdat) -{ - flags_rebuild(); - cpu_state.flags |= C_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTD(uint32_t fetchdat) -{ - cpu_state.flags |= D_FLAG; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} -static int opSTI(uint32_t fetchdat) -{ - if (!IOPLp) - { - if ((!(cpu_state.eflags & VM_FLAG) && (cr4 & CR4_PVI)) || - ((cpu_state.eflags & VM_FLAG) && (cr4 & CR4_VME))) - { - if (cpu_state.eflags & VIP_FLAG) - { - x86gpf(NULL,0); - return 1; - } - else - cpu_state.eflags |= VIF_FLAG; - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - cpu_state.flags |= I_FLAG; - - /*First instruction after STI will always execute, regardless of whether - there is a pending interrupt*/ - cpu_end_block_after_ins = 2; - - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; -} - -static int opSAHF(uint32_t fetchdat) -{ - flags_rebuild(); - cpu_state.flags = (cpu_state.flags & 0xff00) | (AH & 0xd5) | 2; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); #if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; + codegen_flags_changed = 0; #endif - return 0; + return 0; } -static int opLAHF(uint32_t fetchdat) +static int +opPOPFD(uint32_t fetchdat) { - flags_rebuild(); - AH = cpu_state.flags & 0xff; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; -} + uint32_t templ; -static int opPUSHF(uint32_t fetchdat) -{ - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint16_t temp; + if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) { + x86gpf(NULL, 0); + return 1; + } - flags_rebuild(); - temp = (cpu_state.flags & ~I_FLAG) | 0x3000; - if (cpu_state.eflags & VIF_FLAG) - temp |= I_FLAG; - PUSH_W(temp); - } - else - { - x86gpf(NULL,0); - return 1; - } - } - else - { - flags_rebuild(); - PUSH_W(cpu_state.flags); - } - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opPUSHFD(uint32_t fetchdat) -{ - uint16_t tempw; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - if (cpu_CR4_mask & CR4_VME) tempw = cpu_state.eflags & 0x3c; - else if (CPUID) tempw = cpu_state.eflags & 0x24; - else tempw = cpu_state.eflags & 4; - flags_rebuild(); - PUSH_L(cpu_state.flags | (tempw << 16)); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} + templ = POP_L(); + if (cpu_state.abrt) + return 1; -static int opPOPF_186(uint32_t fetchdat) -{ - uint16_t tempw; + if (!(CPL) || !(msw & 1)) + cpu_state.flags = (templ & 0x7fd5) | 2; + else if (IOPLp) + cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; + else + cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } + templ &= (is486 || isibm486) ? 0x3c0000 : 0; + templ |= ((cpu_state.eflags & 3) << 16); + if (cpu_CR4_mask & CR4_VME) + cpu_state.eflags = (templ >> 16) & 0x3f; + else if (CPUID) + cpu_state.eflags = (templ >> 16) & 0x27; + else if (is486 || isibm486) + cpu_state.eflags = (templ >> 16) & 7; + else + cpu_state.eflags = (templ >> 16) & 3; - tempw = POP_W(); if (cpu_state.abrt) return 1; + flags_extract(); - if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); #if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; + codegen_flags_changed = 0; #endif - return 0; -} -static int opPOPF_286(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - tempw = POP_W(); if (cpu_state.abrt) return 1; - - if (!(msw & 1)) cpu_state.flags = (cpu_state.flags & 0x7000) | (tempw & 0x0fd5) | 2; - else if (!(CPL)) cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPF(uint32_t fetchdat) -{ - uint16_t tempw; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - if (cr4 & CR4_VME) - { - uint32_t old_esp = ESP; - - tempw = POP_W(); - if (cpu_state.abrt) - { - - ESP = old_esp; - return 1; - } - - if ((tempw & T_FLAG) || ((tempw & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) - { - ESP = old_esp; - x86gpf(NULL, 0); - return 1; - } - if (tempw & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - else - { - x86gpf(NULL, 0); - return 1; - } - } - else - { - tempw = POP_W(); - if (cpu_state.abrt) - return 1; - - if (!(CPL) || !(msw & 1)) - cpu_state.flags = (tempw & 0x7fd5) | 2; - else if (IOPLp) - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempw & 0x4fd5) | 2; - else - cpu_state.flags = (cpu_state.flags & 0x3200) | (tempw & 0x4dd5) | 2; - } - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; -} -static int opPOPFD(uint32_t fetchdat) -{ - uint32_t templ; - - if ((cpu_state.eflags & VM_FLAG) && (IOPL < 3)) - { - x86gpf(NULL, 0); - return 1; - } - - templ = POP_L(); if (cpu_state.abrt) return 1; - - if (!(CPL) || !(msw & 1)) cpu_state.flags = (templ & 0x7fd5) | 2; - else if (IOPLp) cpu_state.flags = (cpu_state.flags & 0x3000) | (templ & 0x4fd5) | 2; - else cpu_state.flags = (cpu_state.flags & 0x3200) | (templ & 0x4dd5) | 2; - - templ &= (is486 || isibm486) ? 0x3c0000 : 0; - templ |= ((cpu_state.eflags&3) << 16); - if (cpu_CR4_mask & CR4_VME) cpu_state.eflags = (templ >> 16) & 0x3f; - else if (CPUID) cpu_state.eflags = (templ >> 16) & 0x27; - else if (is486 || isibm486) cpu_state.eflags = (templ >> 16) & 7; - else cpu_state.eflags = (templ >> 16) & 3; - - flags_extract(); - - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - -#if (defined(USE_DYNAREC) && defined(USE_NEW_DYNAREC)) - codegen_flags_changed = 0; -#endif - - return 0; + return 0; } diff --git a/src/cpu/x86_ops_fpu.h b/src/cpu/x86_ops_fpu.h index a1976f268..314ec321b 100644 --- a/src/cpu/x86_ops_fpu.h +++ b/src/cpu/x86_ops_fpu.h @@ -1,85 +1,101 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -static int opESCAPE_d8_a16(uint32_t fetchdat) +static int +opESCAPE_d8_a16(uint32_t fetchdat) { - return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_d8_a32(uint32_t fetchdat) +static int +opESCAPE_d8_a32(uint32_t fetchdat) { - return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_d8_a32[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_d9_a16(uint32_t fetchdat) +static int +opESCAPE_d9_a16(uint32_t fetchdat) { - return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_d9_a32(uint32_t fetchdat) +static int +opESCAPE_d9_a32(uint32_t fetchdat) { - return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_d9_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_da_a16(uint32_t fetchdat) +static int +opESCAPE_da_a16(uint32_t fetchdat) { - return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_da_a32(uint32_t fetchdat) +static int +opESCAPE_da_a32(uint32_t fetchdat) { - return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_da_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_db_a16(uint32_t fetchdat) +static int +opESCAPE_db_a16(uint32_t fetchdat) { - return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_db_a32(uint32_t fetchdat) +static int +opESCAPE_db_a32(uint32_t fetchdat) { - return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_db_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_dc_a16(uint32_t fetchdat) +static int +opESCAPE_dc_a16(uint32_t fetchdat) { - return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_dc_a32(uint32_t fetchdat) +static int +opESCAPE_dc_a32(uint32_t fetchdat) { - return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); + return x86_opcodes_dc_a32[(fetchdat >> 3) & 0x1f](fetchdat); } -static int opESCAPE_dd_a16(uint32_t fetchdat) +static int +opESCAPE_dd_a16(uint32_t fetchdat) { - return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_dd_a32(uint32_t fetchdat) +static int +opESCAPE_dd_a32(uint32_t fetchdat) { - return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_dd_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_de_a16(uint32_t fetchdat) +static int +opESCAPE_de_a16(uint32_t fetchdat) { - return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_de_a32(uint32_t fetchdat) +static int +opESCAPE_de_a32(uint32_t fetchdat) { - return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_de_a32[fetchdat & 0xff](fetchdat); } -static int opESCAPE_df_a16(uint32_t fetchdat) +static int +opESCAPE_df_a16(uint32_t fetchdat) { - return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); + return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } -static int opESCAPE_df_a32(uint32_t fetchdat) +static int +opESCAPE_df_a32(uint32_t fetchdat) { - return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); + return x86_opcodes_df_a32[fetchdat & 0xff](fetchdat); } -static int opWAIT(uint32_t fetchdat) +static int +opWAIT(uint32_t fetchdat) { - if ((cr0 & 0xa) == 0xa) - { - x86_int(7); - return 1; - } - CLOCK_CYCLES(4); - return 0; + if ((cr0 & 0xa) == 0xa) { + x86_int(7); + return 1; + } + CLOCK_CYCLES(4); + return 0; } diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index 2394e18f4..8940a98a0 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -19,65 +19,63 @@ opSYSENTER(uint32_t fetchdat) int ret = sysenter(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int opSYSEXIT(uint32_t fetchdat) { int ret = sysexit(fetchdat); if (ret <= 1) { - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 7, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - CPU_BLOCK_END(); + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + CPU_BLOCK_END(); } return ret; } - static int fx_save_stor_common(uint32_t fetchdat, int bits) { - uint8_t fxinst = 0; - uint16_t twd = x87_gettag(); - uint32_t old_eaaddr = 0; - uint8_t ftwb = 0; - uint16_t rec_ftw = 0; - uint16_t fpus = 0; + uint8_t fxinst = 0; + uint16_t twd = x87_gettag(); + uint32_t old_eaaddr = 0; + uint8_t ftwb = 0; + uint16_t rec_ftw = 0; + uint16_t fpus = 0; uint64_t *p; if (CPUID < 0x650) - return ILLEGAL(fetchdat); + return ILLEGAL(fetchdat); FP_ENTER(); if (bits == 32) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); } else { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); } if (cpu_state.eaaddr & 0xf) { - x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); - x86gpf(NULL, 0); - return cpu_state.abrt; + x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); + x86gpf(NULL, 0); + return cpu_state.abrt; } fxinst = (rmdat >> 3) & 7; if ((fxinst > 1) || (cpu_mod == 3)) { - x86illegal(); - return cpu_state.abrt; + x86illegal(); + return cpu_state.abrt; } FP_ENTER(); @@ -85,170 +83,186 @@ fx_save_stor_common(uint32_t fetchdat, int bits) old_eaaddr = cpu_state.eaaddr; if (fxinst == 1) { - /* FXRSTOR */ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - fpus = readmemw(easeg, cpu_state.eaaddr + 2); - cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.TOP = (fpus >> 11) & 7; - cpu_state.npxs &= fpus & ~0x3800; + /* FXRSTOR */ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + fpus = readmemw(easeg, cpu_state.eaaddr + 2); + cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.TOP = (fpus >> 11) & 7; + cpu_state.npxs &= fpus & ~0x3800; - x87_pc_off = readmeml(easeg, cpu_state.eaaddr+8); - x87_pc_seg = readmemw(easeg, cpu_state.eaaddr+12); + x87_pc_off = readmeml(easeg, cpu_state.eaaddr + 8); + x87_pc_seg = readmemw(easeg, cpu_state.eaaddr + 12); - ftwb = readmemb(easeg, cpu_state.eaaddr + 4); + ftwb = readmemb(easeg, cpu_state.eaaddr + 4); - if (ftwb & 0x01) rec_ftw |= 0x0003; - if (ftwb & 0x02) rec_ftw |= 0x000C; - if (ftwb & 0x04) rec_ftw |= 0x0030; - if (ftwb & 0x08) rec_ftw |= 0x00C0; - if (ftwb & 0x10) rec_ftw |= 0x0300; - if (ftwb & 0x20) rec_ftw |= 0x0C00; - if (ftwb & 0x40) rec_ftw |= 0x3000; - if (ftwb & 0x80) rec_ftw |= 0xC000; + if (ftwb & 0x01) + rec_ftw |= 0x0003; + if (ftwb & 0x02) + rec_ftw |= 0x000C; + if (ftwb & 0x04) + rec_ftw |= 0x0030; + if (ftwb & 0x08) + rec_ftw |= 0x00C0; + if (ftwb & 0x10) + rec_ftw |= 0x0300; + if (ftwb & 0x20) + rec_ftw |= 0x0C00; + if (ftwb & 0x40) + rec_ftw |= 0x3000; + if (ftwb & 0x80) + rec_ftw |= 0xC000; - x87_op_off = readmeml(easeg, cpu_state.eaaddr+16); - x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; - x87_op_seg = readmemw(easeg, cpu_state.eaaddr+20); + x87_op_off = readmeml(easeg, cpu_state.eaaddr + 16); + x87_op_off |= (readmemw(easeg, cpu_state.eaaddr + 6) >> 12) << 16; + x87_op_seg = readmemw(easeg, cpu_state.eaaddr + 20); - cpu_state.eaaddr = old_eaaddr + 32; - x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); x87_ld_frstor(0); + cpu_state.eaaddr = old_eaaddr + 32; + x87_ldmmx(&(cpu_state.MM[0]), &(cpu_state.MM_w4[0])); + x87_ld_frstor(0); - cpu_state.eaaddr = old_eaaddr + 48; - x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); x87_ld_frstor(1); + cpu_state.eaaddr = old_eaaddr + 48; + x87_ldmmx(&(cpu_state.MM[1]), &(cpu_state.MM_w4[1])); + x87_ld_frstor(1); - cpu_state.eaaddr = old_eaaddr + 64; - x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); x87_ld_frstor(2); + cpu_state.eaaddr = old_eaaddr + 64; + x87_ldmmx(&(cpu_state.MM[2]), &(cpu_state.MM_w4[2])); + x87_ld_frstor(2); - cpu_state.eaaddr = old_eaaddr + 80; - x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); x87_ld_frstor(3); + cpu_state.eaaddr = old_eaaddr + 80; + x87_ldmmx(&(cpu_state.MM[3]), &(cpu_state.MM_w4[3])); + x87_ld_frstor(3); - cpu_state.eaaddr = old_eaaddr + 96; - x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); x87_ld_frstor(4); + cpu_state.eaaddr = old_eaaddr + 96; + x87_ldmmx(&(cpu_state.MM[4]), &(cpu_state.MM_w4[4])); + x87_ld_frstor(4); - cpu_state.eaaddr = old_eaaddr + 112; - x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); x87_ld_frstor(5); + cpu_state.eaaddr = old_eaaddr + 112; + x87_ldmmx(&(cpu_state.MM[5]), &(cpu_state.MM_w4[5])); + x87_ld_frstor(5); - cpu_state.eaaddr = old_eaaddr + 128; - x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); x87_ld_frstor(6); + cpu_state.eaaddr = old_eaaddr + 128; + x87_ldmmx(&(cpu_state.MM[6]), &(cpu_state.MM_w4[6])); + x87_ld_frstor(6); - cpu_state.eaaddr = old_eaaddr + 144; - x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); x87_ld_frstor(7); + cpu_state.eaaddr = old_eaaddr + 144; + x87_ldmmx(&(cpu_state.MM[7]), &(cpu_state.MM_w4[7])); + x87_ld_frstor(7); - cpu_state.ismmx = 0; - /*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *) cpu_state.tag; + cpu_state.ismmx = 0; + /*Horrible hack, but as 86Box doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) #else - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) #endif - cpu_state.ismmx = 1; + cpu_state.ismmx = 1; - x87_settag(rec_ftw); + x87_settag(rec_ftw); - CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); } else { - /* FXSAVE */ - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; - if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; - if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; - if ((twd & 0x00C0) == 0x00C0) ftwb |= 0x08; - if ((twd & 0x0300) == 0x0300) ftwb |= 0x10; - if ((twd & 0x0C00) == 0x0C00) ftwb |= 0x20; - if ((twd & 0x3000) == 0x3000) ftwb |= 0x40; - if ((twd & 0xC000) == 0xC000) ftwb |= 0x80; + /* FXSAVE */ + if ((twd & 0x0003) == 0x0003) + ftwb |= 0x01; + if ((twd & 0x000C) == 0x000C) + ftwb |= 0x02; + if ((twd & 0x0030) == 0x0030) + ftwb |= 0x04; + if ((twd & 0x00C0) == 0x00C0) + ftwb |= 0x08; + if ((twd & 0x0300) == 0x0300) + ftwb |= 0x10; + if ((twd & 0x0C00) == 0x0C00) + ftwb |= 0x20; + if ((twd & 0x3000) == 0x3000) + ftwb |= 0x40; + if ((twd & 0xC000) == 0xC000) + ftwb |= 0x80; - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememb(easeg,cpu_state.eaaddr+4,ftwb); + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememb(easeg, cpu_state.eaaddr + 4, ftwb); - writememw(easeg,cpu_state.eaaddr+6,(x87_op_off>>16)<<12); - writememl(easeg,cpu_state.eaaddr+8,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 6, (x87_op_off >> 16) << 12); + writememl(easeg, cpu_state.eaaddr + 8, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+16,x87_op_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_seg); + writememl(easeg, cpu_state.eaaddr + 16, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_seg); - cpu_state.eaaddr = old_eaaddr + 32; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); + cpu_state.eaaddr = old_eaaddr + 32; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[0]) : x87_st_fsave(0); - cpu_state.eaaddr = old_eaaddr + 48; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); + cpu_state.eaaddr = old_eaaddr + 48; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[1]) : x87_st_fsave(1); - cpu_state.eaaddr = old_eaaddr + 64; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); + cpu_state.eaaddr = old_eaaddr + 64; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[2]) : x87_st_fsave(2); - cpu_state.eaaddr = old_eaaddr + 80; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); + cpu_state.eaaddr = old_eaaddr + 80; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[3]) : x87_st_fsave(3); - cpu_state.eaaddr = old_eaaddr + 96; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); + cpu_state.eaaddr = old_eaaddr + 96; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[4]) : x87_st_fsave(4); - cpu_state.eaaddr = old_eaaddr + 112; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); + cpu_state.eaaddr = old_eaaddr + 112; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[5]) : x87_st_fsave(5); - cpu_state.eaaddr = old_eaaddr + 128; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); + cpu_state.eaaddr = old_eaaddr + 128; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[6]) : x87_st_fsave(6); - cpu_state.eaaddr = old_eaaddr + 144; - cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); + cpu_state.eaaddr = old_eaaddr + 144; + cpu_state.ismmx ? x87_stmmx(cpu_state.MM[7]) : x87_st_fsave(7); - cpu_state.eaaddr = old_eaaddr; + cpu_state.eaaddr = old_eaaddr; - cpu_state.npxc = 0x37F; + cpu_state.npxc = 0x37F; codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC *p = 0; #else *p = 0x0303030303030303ll; #endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; - CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); } return cpu_state.abrt; } - static int opFXSAVESTOR_a16(uint32_t fetchdat) { return fx_save_stor_common(fetchdat, 16); } - static int opFXSAVESTOR_a32(uint32_t fetchdat) { return fx_save_stor_common(fetchdat, 32); } - static int opHINT_NOP_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); return 0; } - static int opHINT_NOP_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); return 0; } diff --git a/src/cpu/x86_ops_inc_dec.h b/src/cpu/x86_ops_inc_dec.h index 682662851..3eb908c57 100644 --- a/src/cpu/x86_ops_inc_dec.h +++ b/src/cpu/x86_ops_inc_dec.h @@ -1,12 +1,12 @@ -#define INC_DEC_OP(name, reg, inc, setflags) \ - static int op ## name (uint32_t fetchdat) \ - { \ - setflags(reg, 1); \ - reg += inc; \ - CLOCK_CYCLES(timing_rr); \ - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define INC_DEC_OP(name, reg, inc, setflags) \ + static int op##name(uint32_t fetchdat) \ + { \ + setflags(reg, 1); \ + reg += inc; \ + CLOCK_CYCLES(timing_rr); \ + PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } INC_DEC_OP(INC_AX, AX, 1, setadd16nc) INC_DEC_OP(INC_BX, BX, 1, setadd16nc) @@ -44,50 +44,57 @@ INC_DEC_OP(DEC_EDI, EDI, -1, setsub32nc) INC_DEC_OP(DEC_EBP, EBP, -1, setsub32nc) INC_DEC_OP(DEC_ESP, ESP, -1, setsub32nc) - -static int opINCDEC_b_a16(uint32_t fetchdat) +static int +opINCDEC_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp=geteab(); if (cpu_state.abrt) return 1; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + if (rmdat & 0x38) { + seteab(temp - 1); + if (cpu_state.abrt) + return 1; + setsub8nc(temp, 1); + } else { + seteab(temp + 1); + if (cpu_state.abrt) + return 1; + setadd8nc(temp, 1); + } + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opINCDEC_b_a32(uint32_t fetchdat) +static int +opINCDEC_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp=geteab(); if (cpu_state.abrt) return 1; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; - if (rmdat&0x38) - { - seteab(temp - 1); if (cpu_state.abrt) return 1; - setsub8nc(temp, 1); - } - else - { - seteab(temp + 1); if (cpu_state.abrt) return 1; - setadd8nc(temp, 1); - } - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + if (rmdat & 0x38) { + seteab(temp - 1); + if (cpu_state.abrt) + return 1; + setsub8nc(temp, 1); + } else { + seteab(temp + 1); + if (cpu_state.abrt) + return 1; + setadd8nc(temp, 1); + } + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_int.h b/src/cpu/x86_ops_int.h index 0074aec29..a73ed62e0 100644 --- a/src/cpu/x86_ops_int.h +++ b/src/cpu/x86_ops_int.h @@ -1,94 +1,96 @@ -static int opINT3(uint32_t fetchdat) +static int +opINT3(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); #ifdef USE_GDBSTUB - if (gdbstub_int3()) - return 1; + if (gdbstub_int3()) + return 1; #endif - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(3); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); return 1; + } + x86_int_sw(3); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINT1(uint32_t fetchdat) +static int +opINT1(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - x86_int_sw(1); - CLOCK_CYCLES((is486) ? 44 : 59); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + int cycles_old = cycles; + UN_USED(cycles_old); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); return 1; + } + x86_int_sw(1); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINT(uint32_t fetchdat) +static int +opINT(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); - uint8_t temp = getbytef(); + int cycles_old = cycles; + UN_USED(cycles_old); + uint8_t temp = getbytef(); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t t; - uint8_t d; + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t t; + uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66) - 32; - cpl_override = 0; - if (cpu_state.abrt) return 1; + cpl_override = 1; + t = readmemw(tr.base, 0x66) - 32; + cpl_override = 0; + if (cpu_state.abrt) + return 1; - t += (temp >> 3); - if (t <= tr.limit) - { - cpl_override = 1; - d = readmemb(tr.base, t);// + (temp >> 3)); - cpl_override = 0; - if (cpu_state.abrt) return 1; + t += (temp >> 3); + if (t <= tr.limit) { + cpl_override = 1; + d = readmemb(tr.base, t); // + (temp >> 3)); + cpl_override = 0; + if (cpu_state.abrt) + return 1; - if (!(d & (1 << (temp & 7)))) - { - x86_int_sw_rm(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); - return 1; - } - } + if (!(d & (1 << (temp & 7)))) { + x86_int_sw_rm(temp); + PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0); + return 1; } - x86gpf_expected(NULL,0); - return 1; + } } - - x86_int_sw(temp); - PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); + x86gpf_expected(NULL, 0); return 1; + } + + x86_int_sw(temp); + PREFETCH_RUN(cycles_old - cycles, 2, -1, 0, 0, 0, 0, 0); + return 1; } -static int opINTO(uint32_t fetchdat) +static int +opINTO(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); - return 1; - } - if (VF_SET()) - { - cpu_state.oldpc = cpu_state.pc; - x86_int_sw(4); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); - return 1; - } - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (VF_SET()) { + cpu_state.oldpc = cpu_state.pc; + x86_int_sw(4); + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 0, 0, 0, 0); + return 1; + } + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } diff --git a/src/cpu/x86_ops_io.h b/src/cpu/x86_ops_io.h index 50d7d94d1..c4d46404d 100644 --- a/src/cpu/x86_ops_io.h +++ b/src/cpu/x86_ops_io.h @@ -1,146 +1,158 @@ -static int opIN_AL_imm(uint32_t fetchdat) +static int +opIN_AL_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - AL = inb(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + AL = inb(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opIN_AX_imm(uint32_t fetchdat) +static int +opIN_AX_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - AX = inw(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + AX = inw(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opIN_EAX_imm(uint32_t fetchdat) +static int +opIN_EAX_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - EAX = inl(port); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + check_io_perm(port + 2); + check_io_perm(port + 3); + EAX = inl(port); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_AL_imm(uint32_t fetchdat) +static int +opOUT_AL_imm(uint32_t fetchdat) { - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - outb(port, AL); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (port == 0x64) - return x86_was_reset; - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_AX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - outw(port, AX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opOUT_EAX_imm(uint32_t fetchdat) -{ - uint16_t port = (uint16_t)getbytef(); - check_io_perm(port); - check_io_perm(port + 1); - check_io_perm(port + 2); - check_io_perm(port + 3); - outl(port, EAX); - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opIN_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - AL = inb(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_AX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - AX = inw(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 1,0,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} -static int opIN_EAX_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - EAX = inl(DX); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 1, -1, 0,1,0,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; -} - -static int opOUT_AL_DX(uint32_t fetchdat) -{ - check_io_perm(DX); - outb(DX, AL); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + outb(port, AL); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); + if (port == 0x64) return x86_was_reset; + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_AX_DX(uint32_t fetchdat) +static int +opOUT_AX_imm(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - outw(DX, AX); - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 1, -1, 0,0,1,0, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + outw(port, AX); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } -static int opOUT_EAX_DX(uint32_t fetchdat) +static int +opOUT_EAX_imm(uint32_t fetchdat) { - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - outl(DX, EAX); - PREFETCH_RUN(11, 1, -1, 0,0,0,1, 0); - if (nmi && nmi_enable && nmi_mask) - return 1; - return 0; + uint16_t port = (uint16_t) getbytef(); + check_io_perm(port); + check_io_perm(port + 1); + check_io_perm(port + 2); + check_io_perm(port + 3); + outl(port, EAX); + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} + +static int +opIN_AL_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + AL = inb(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opIN_AX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + AX = inw(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opIN_EAX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + EAX = inl(DX); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} + +static int +opOUT_AL_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + outb(DX, AL); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return x86_was_reset; +} +static int +opOUT_AX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + outw(DX, AX); + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; +} +static int +opOUT_EAX_DX(uint32_t fetchdat) +{ + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + outl(DX, EAX); + PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0); + if (nmi && nmi_enable && nmi_mask) + return 1; + return 0; } diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 7f9df37d7..2a338afdc 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -1,74 +1,73 @@ -#define cond_O ( VF_SET()) +#define cond_O (VF_SET()) #define cond_NO (!VF_SET()) -#define cond_B ( CF_SET()) +#define cond_B (CF_SET()) #define cond_NB (!CF_SET()) -#define cond_E ( ZF_SET()) +#define cond_E (ZF_SET()) #define cond_NE (!ZF_SET()) -#define cond_BE ( CF_SET() || ZF_SET()) +#define cond_BE (CF_SET() || ZF_SET()) #define cond_NBE (!CF_SET() && !ZF_SET()) -#define cond_S ( NF_SET()) +#define cond_S (NF_SET()) #define cond_NS (!NF_SET()) -#define cond_P ( PF_SET()) +#define cond_P (PF_SET()) #define cond_NP (!PF_SET()) #define cond_L (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0)) #define cond_NL (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0)) -#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) +#define cond_LE (((NF_SET()) ? 1 : 0) != ((VF_SET()) ? 1 : 0) || (ZF_SET())) #define cond_NLE (((NF_SET()) ? 1 : 0) == ((VF_SET()) ? 1 : 0) && (!ZF_SET())) -#define opJ(condition) \ - static int opJ ## condition(uint32_t fetchdat) \ - { \ - int8_t offset = (int8_t)getbytef(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - if (!(cpu_state.op32 & 0x100)) \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 2, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 2, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _w(uint32_t fetchdat) \ - { \ - int16_t offset = (int16_t)getwordf(); \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - cpu_state.pc &= 0xffff; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 3, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 3, -1, 0,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opJ ## condition ## _l(uint32_t fetchdat) \ - { \ - uint32_t offset = getlong(); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(timing_bnt); \ - if (cond_ ## condition) \ - { \ - cpu_state.pc += offset; \ - CLOCK_CYCLES_ALWAYS(timing_bt); \ - CPU_BLOCK_END(); \ - PREFETCH_RUN(timing_bt+timing_bnt, 5, -1, 0,0,0,0, 0); \ - PREFETCH_FLUSH(); \ - return 1; \ - } \ - PREFETCH_RUN(timing_bnt, 5, -1, 0,0,0,0, 0); \ - return 0; \ - } \ +#define opJ(condition) \ + static int opJ##condition(uint32_t fetchdat) \ + { \ + int8_t offset = (int8_t) getbytef(); \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + if (!(cpu_state.op32 & 0x100)) \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 2, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opJ##condition##_w(uint32_t fetchdat) \ + { \ + int16_t offset = (int16_t) getwordf(); \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + cpu_state.pc &= 0xffff; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 3, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opJ##condition##_l(uint32_t fetchdat) \ + { \ + uint32_t offset = getlong(); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(timing_bnt); \ + if (cond_##condition) { \ + cpu_state.pc += offset; \ + CLOCK_CYCLES_ALWAYS(timing_bt); \ + CPU_BLOCK_END(); \ + PREFETCH_RUN(timing_bt + timing_bnt, 5, -1, 0, 0, 0, 0, 0); \ + PREFETCH_FLUSH(); \ + return 1; \ + } \ + PREFETCH_RUN(timing_bnt, 5, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } opJ(O) opJ(NO) @@ -87,294 +86,321 @@ opJ(NL) opJ(LE) opJ(NLE) - - -static int opLOOPNE_w(uint32_t fetchdat) + static int opLOOPNE_w(uint32_t fetchdat) { - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && !ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPNE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && !ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOPE_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX && ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOPE_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX && ZF_SET()) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opLOOP_w(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (CX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} -static int opLOOP_l(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - ECX--; - CLOCK_CYCLES((is486) ? 7 : 11); - PREFETCH_RUN(11, 2, -1, 0,0,0,0, 0); - if (ECX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - PREFETCH_FLUSH(); - return 1; - } - return 0; -} - -static int opJCXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!CX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} -static int opJECXZ(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); - CLOCK_CYCLES(5); - if (!ECX) - { - cpu_state.pc += offset; - if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; - CLOCK_CYCLES(4); - CPU_BLOCK_END(); - PREFETCH_RUN(9, 2, -1, 0,0,0,0, 0); - PREFETCH_FLUSH(); - return 1; - } - PREFETCH_RUN(5, 2, -1, 0,0,0,0, 0); - return 0; -} - - -static int opJMP_r8(uint32_t fetchdat) -{ - int8_t offset = (int8_t)getbytef(); + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX && !ZF_SET()) { cpu_state.pc += offset; if (!(cpu_state.op32 & 0x100)) - cpu_state.pc &= 0xffff; + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 2, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_r16(uint32_t fetchdat) +static int +opLOOPNE_l(uint32_t fetchdat) { - int16_t offset = (int16_t)getwordf(); + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX && !ZF_SET()) { cpu_state.pc += offset; - cpu_state.pc &= 0xffff; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_r32(uint32_t fetchdat) + +static int +opLOOPE_w(uint32_t fetchdat) { - int32_t offset = (int32_t)getlong(); if (cpu_state.abrt) return 1; + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX && ZF_SET()) { cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; +} +static int +opLOOPE_l(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX && ZF_SET()) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + PREFETCH_FLUSH(); + return 1; + } + return 0; } -static int opJMP_far_a16(uint32_t fetchdat) +static int +opLOOP_w(uint32_t fetchdat) { - uint16_t addr, seg; - uint32_t old_pc; - addr = getwordf(); - seg = getword(); if (cpu_state.abrt) return 1; - old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + int8_t offset = (int8_t) getbytef(); + CX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - PREFETCH_RUN(11, 5, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opJMP_far_a32(uint32_t fetchdat) +static int +opLOOP_l(uint32_t fetchdat) { - uint16_t seg; - uint32_t addr, old_pc; - addr = getlong(); - seg = getword(); if (cpu_state.abrt) return 1; - old_pc = cpu_state.pc; - cpu_state.pc = addr; - loadcsjmp(seg, old_pc); + int8_t offset = (int8_t) getbytef(); + ECX--; + CLOCK_CYCLES((is486) ? 7 : 11); + PREFETCH_RUN(11, 2, -1, 0, 0, 0, 0, 0); + if (ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; CPU_BLOCK_END(); - PREFETCH_RUN(11, 7, -1, 0,0,0,0, 0); PREFETCH_FLUSH(); - return 0; + return 1; + } + return 0; } -static int opCALL_r16(uint32_t fetchdat) +static int +opJCXZ(uint32_t fetchdat) { - int16_t addr = (int16_t)getwordf(); - PUSH_W(cpu_state.pc); - cpu_state.pc += addr; + int8_t offset = (int8_t) getbytef(); + CLOCK_CYCLES(5); + if (!CX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 1; + } + PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); + return 0; +} +static int +opJECXZ(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + CLOCK_CYCLES(5); + if (!ECX) { + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) + cpu_state.pc &= 0xffff; + CLOCK_CYCLES(4); + CPU_BLOCK_END(); + PREFETCH_RUN(9, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 1; + } + PREFETCH_RUN(5, 2, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opJMP_r8(uint32_t fetchdat) +{ + int8_t offset = (int8_t) getbytef(); + cpu_state.pc += offset; + if (!(cpu_state.op32 & 0x100)) cpu_state.pc &= 0xffff; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 3, -1, 0,0,1,0, 0); - PREFETCH_FLUSH(); - return 0; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 2, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opCALL_r32(uint32_t fetchdat) +static int +opJMP_r16(uint32_t fetchdat) { - int32_t addr = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(cpu_state.pc); - cpu_state.pc += addr; - CPU_BLOCK_END(); - CLOCK_CYCLES((is486) ? 3 : 7); - PREFETCH_RUN(7, 5, -1, 0,0,0,1, 0); - PREFETCH_FLUSH(); - return 0; + int16_t offset = (int16_t) getwordf(); + cpu_state.pc += offset; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } - -static int opRET_w(uint32_t fetchdat) +static int +opJMP_r32(uint32_t fetchdat) { - uint16_t ret; - - ret = POP_W(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + int32_t offset = (int32_t) getlong(); + if (cpu_state.abrt) + return 1; + cpu_state.pc += offset; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 5, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRET_l(uint32_t fetchdat) + +static int +opJMP_far_a16(uint32_t fetchdat) { - uint32_t ret; - - ret = POP_L(); if (cpu_state.abrt) return 1; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 1, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t addr, seg; + uint32_t old_pc; + addr = getwordf(); + seg = getword(); + if (cpu_state.abrt) + return 1; + old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(11, 5, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } - -static int opRET_w_imm(uint32_t fetchdat) +static int +opJMP_far_a32(uint32_t fetchdat) { - uint16_t ret; - uint16_t offset = getwordf(); - - ret = POP_W(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 1,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + uint16_t seg; + uint32_t addr, old_pc; + addr = getlong(); + seg = getword(); + if (cpu_state.abrt) + return 1; + old_pc = cpu_state.pc; + cpu_state.pc = addr; + loadcsjmp(seg, old_pc); + CPU_BLOCK_END(); + PREFETCH_RUN(11, 7, -1, 0, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRET_l_imm(uint32_t fetchdat) + +static int +opCALL_r16(uint32_t fetchdat) { - uint32_t ret; - uint16_t offset = getwordf(); - - ret = POP_L(); if (cpu_state.abrt) return 1; - if (stack32) ESP += offset; - else SP += offset; - cpu_state.pc = ret; - CPU_BLOCK_END(); - - CLOCK_CYCLES((is486) ? 5 : 10); - PREFETCH_RUN(10, 5, -1, 0,1,0,0, 0); - PREFETCH_FLUSH(); - return 0; + int16_t addr = (int16_t) getwordf(); + PUSH_W(cpu_state.pc); + cpu_state.pc += addr; + cpu_state.pc &= 0xffff; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 3, -1, 0, 0, 1, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opCALL_r32(uint32_t fetchdat) +{ + int32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + PUSH_L(cpu_state.pc); + cpu_state.pc += addr; + CPU_BLOCK_END(); + CLOCK_CYCLES((is486) ? 3 : 7); + PREFETCH_RUN(7, 5, -1, 0, 0, 0, 1, 0); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRET_w(uint32_t fetchdat) +{ + uint16_t ret; + + ret = POP_W(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 1, -1, 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRET_l(uint32_t fetchdat) +{ + uint32_t ret; + + ret = POP_L(); + if (cpu_state.abrt) + return 1; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 1, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} + +static int +opRET_w_imm(uint32_t fetchdat) +{ + uint16_t ret; + uint16_t offset = getwordf(); + + ret = POP_W(); + if (cpu_state.abrt) + return 1; + if (stack32) + ESP += offset; + else + SP += offset; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 1, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; +} +static int +opRET_l_imm(uint32_t fetchdat) +{ + uint32_t ret; + uint16_t offset = getwordf(); + + ret = POP_L(); + if (cpu_state.abrt) + return 1; + if (stack32) + ESP += offset; + else + SP += offset; + cpu_state.pc = ret; + CPU_BLOCK_END(); + + CLOCK_CYCLES((is486) ? 5 : 10); + PREFETCH_RUN(10, 5, -1, 0, 1, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 7fde5dacc..bd1139ba4 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -1,971 +1,1058 @@ -static int opCBW(uint32_t fetchdat) +static int +opCBW(uint32_t fetchdat) { - AH = (AL & 0x80) ? 0xff : 0; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + AH = (AL & 0x80) ? 0xff : 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCWDE(uint32_t fetchdat) +static int +opCWDE(uint32_t fetchdat) { - EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + EAX = (AX & 0x8000) ? (0xffff0000 | AX) : AX; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCWD(uint32_t fetchdat) +static int +opCWD(uint32_t fetchdat) { - DX = (AX & 0x8000) ? 0xFFFF : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + DX = (AX & 0x8000) ? 0xFFFF : 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opCDQ(uint32_t fetchdat) +static int +opCDQ(uint32_t fetchdat) { - EDX = (EAX & 0x80000000) ? 0xffffffff : 0; - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 1, -1, 0,0,0,0, 0); - return 0; + EDX = (EAX & 0x80000000) ? 0xffffffff : 0; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opNOP(uint32_t fetchdat) +static int +opNOP(uint32_t fetchdat) { - CLOCK_CYCLES((is486) ? 1 : 3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + CLOCK_CYCLES((is486) ? 1 : 3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opSETALC(uint32_t fetchdat) +static int +opSETALC(uint32_t fetchdat) { - AL = (CF_SET()) ? 0xff : 0; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 1, -1, 0,0,0,0, 0); - return 0; + AL = (CF_SET()) ? 0xff : 0; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 1, -1, 0, 0, 0, 0, 0); + return 0; } - - -static int opF6_a16(uint32_t fetchdat) +static int +opF6_a16(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) { - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - } - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags|=0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF6_a32(uint32_t fetchdat) -{ - int tempws, tempws2 = 0; - uint16_t tempw, src16; - uint8_t src, dst; - int8_t temps; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteab(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST b,#8*/ - case 0x08: - src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - setznp8(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG b*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(0 - dst); if (cpu_state.abrt) return 1; - setsub8(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AL,b*/ - AX = AL * dst; - flags_rebuild(); - if (AH) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(13); - PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AL,b*/ - tempws = (int)((int8_t)AL) * (int)((int8_t)dst); - AX = tempws & 0xffff; - flags_rebuild(); - if (((int16_t)AX >> 7) != 0 && ((int16_t)AX >> 7) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AL,b*/ - src16 = AX; - if (dst) tempw = src16 / dst; - if (dst && !(tempw & 0xff00)) - { - AH = src16 % dst; - AL = (src16 / dst) &0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AL,b*/ - tempws = (int)(int16_t)AX; - if (dst != 0) tempws2 = tempws / (int)((int8_t)dst); - temps = tempws2 & 0xff; - if (dst && ((int)temps == tempws2)) - { - AH = (tempws % (int)((int8_t)dst)) & 0xff; - AL = tempws2 & 0xff; - if (!cpu_iscyrix) - { - flags_rebuild(); - cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ - cpu_state.flags &= ~1; - } - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(19); - PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - - - -static int opF7_w_a16(uint32_t fetchdat) -{ - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 0; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x10: /*NOT w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x18: /*NEG w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF7_w_a32(uint32_t fetchdat) -{ - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 1; - int16_t temps16; - uint16_t src, dst; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteaw(); if (cpu_state.abrt) return 1; - switch (rmdat & 0x38) - { - case 0x00: /*TEST w*/ - case 0x08: - src = getword(); if (cpu_state.abrt) return 1; - setznp16(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x10: /*NOT w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x18: /*NEG w*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(0 - dst); if (cpu_state.abrt) return 1; - setsub16(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - break; - case 0x20: /*MUL AX,w*/ - templ = AX * dst; - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (DX) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x28: /*IMUL AX,w*/ - templ = (int)((int16_t)AX) * (int)((int16_t)dst); - AX = templ & 0xFFFF; - DX = templ >> 16; - flags_rebuild(); - if (((int32_t)templ >> 15) != 0 && ((int32_t)templ >> 15) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(22); - PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x30: /*DIV AX,w*/ - templ = (DX << 16) | AX; - if (dst) templ2 = templ / dst; - if (dst && !(templ2 & 0xffff0000)) - { - DX = templ % dst; - AX = (templ / dst) & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); - x86_int(0); - return 1; - } - CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); - PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - case 0x38: /*IDIV AX,w*/ - tempws = (int)((DX << 16)|AX); - if (dst) tempws2 = tempws / (int)((int16_t)dst); - temps16 = tempws2 & 0xffff; - if ((dst != 0) && ((int)temps16 == tempws2)) - { - DX = tempws % (int)((int16_t)dst); - AX = tempws2 & 0xffff; - if (!cpu_iscyrix) setznp16(AX); /*Not a Cyrix*/ - } - else - { - x86_int(0); - return 1; - } - CLOCK_CYCLES(27); - PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - -static int opF7_l_a16(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x10: /*NOT l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x18: /*NEG l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); - else cpu_state.flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40:38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - break; - - default: - x86illegal(); - } - return 0; -} -static int opF7_l_a32(uint32_t fetchdat) -{ - uint64_t temp64; - uint32_t src, dst; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - dst = geteal(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*TEST l*/ - case 0x08: - src = getlong(); if (cpu_state.abrt) return 1; - setznp32(src & dst); - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x10: /*NOT l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(~dst); if (cpu_state.abrt) return 1; - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x18: /*NEG l*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(0 - dst); if (cpu_state.abrt) return 1; - setsub32(0, dst); - CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); - PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - break; - case 0x20: /*MUL EAX,l*/ - temp64 = (uint64_t)EAX * (uint64_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (EDX) cpu_state.flags |= (C_FLAG|V_FLAG); - else cpu_state.flags &= ~(C_FLAG|V_FLAG); - CLOCK_CYCLES(21); - PREFETCH_RUN(21, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x28: /*IMUL EAX,l*/ - temp64 = (int64_t)(int32_t)EAX * (int64_t)(int32_t)dst; - EAX = temp64 & 0xffffffff; - EDX = temp64 >> 32; - flags_rebuild(); - if (((int64_t)temp64 >> 31) != 0 && ((int64_t)temp64 >> 31) != -1) cpu_state.flags |= (C_FLAG | V_FLAG); - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(38); - PREFETCH_RUN(38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x30: /*DIV EAX,l*/ - if (divl(dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES((is486) ? 40 : 38); - PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - case 0x38: /*IDIV EAX,l*/ - if (idivl((int32_t)dst)) - return 1; - if (!cpu_iscyrix) setznp32(EAX); /*Not a Cyrix*/ - CLOCK_CYCLES(43); - PREFETCH_RUN(43, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - break; - - default: - x86illegal(); - } - return 0; -} - - -static int opHLT(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (smi_line) - enter_smm_check(1); - else if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) - { - CLOCK_CYCLES_ALWAYS(100); - if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) - cpu_state.pc--; - } - else { - CLOCK_CYCLES(5); - } - - CPU_BLOCK_END(); - PREFETCH_RUN(100, 1, -1, 0,0,0,0, 0); - - if (hlt_reset_pending) - softresetx86(); - - return 0; -} - - -static int opLOCK(uint32_t fetchdat) -{ - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 0; - cpu_state.pc++; - - ILLEGAL_ON((fetchdat & 0xff) == 0x90); - - CLOCK_CYCLES(4); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); -} - - - -static int opBOUND_w_a16(uint32_t fetchdat) -{ - int16_t low, high; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) { SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + } + dst = geteab(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST b,#8*/ + case 0x08: + src = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - } + setznp8(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(0 - dst); + if (cpu_state.abrt) + return 1; + setsub8(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x20: /*MUL AL,b*/ + AX = AL * dst; + flags_rebuild(); + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(13); + PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x28: /*IMUL AL,b*/ + tempws = (int) ((int8_t) AL) * (int) ((int8_t) dst); + AX = tempws & 0xffff; + flags_rebuild(); + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x30: /*DIV AL,b*/ + src16 = AX; + if (dst) + tempw = src16 / dst; + if (dst && !(tempw & 0xff00)) { + AH = src16 % dst; + AL = (src16 / dst) & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int) (int16_t) AX; + if (dst != 0) + tempws2 = tempws / (int) ((int8_t) dst); + temps = tempws2 & 0xff; + if (dst && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) dst)) & 0xff; + AL = tempws2 & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(19); + PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 0); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_w_a32(uint32_t fetchdat) +static int +opF6_a32(uint32_t fetchdat) { - int16_t low, high; + int tempws, tempws2 = 0; + uint16_t tempw, src16; + uint8_t src, dst; + int8_t temps; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteaw(); - high = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - - if (((int16_t)cpu_state.regs[cpu_reg].w < low) || ((int16_t)cpu_state.regs[cpu_reg].w > high)) - { - x86_int(5); + dst = geteab(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST b,#8*/ + case 0x08: + src = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - } + setznp8(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 3, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x10: /*NOT b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x18: /*NEG b*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(0 - dst); + if (cpu_state.abrt) + return 1; + setsub8(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x20: /*MUL AL,b*/ + AX = AL * dst; + flags_rebuild(); + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(13); + PREFETCH_RUN(13, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x28: /*IMUL AL,b*/ + tempws = (int) ((int8_t) AL) * (int) ((int8_t) dst); + AX = tempws & 0xffff; + flags_rebuild(); + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x30: /*DIV AL,b*/ + src16 = AX; + if (dst) + tempw = src16 / dst; + if (dst && !(tempw & 0xff00)) { + AH = src16 % dst; + AL = (src16 / dst) & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 16 : 14); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 16 : 14, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x38: /*IDIV AL,b*/ + tempws = (int) (int16_t) AX; + if (dst != 0) + tempws2 = tempws / (int) ((int8_t) dst); + temps = tempws2 & 0xff; + if (dst && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) dst)) & 0xff; + AL = tempws2 & 0xff; + if (!cpu_iscyrix) { + flags_rebuild(); + cpu_state.flags |= 0x8D5; /*Not a Cyrix*/ + cpu_state.flags &= ~1; + } + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(19); + PREFETCH_RUN(19, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2,0,0,0, 1); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_l_a16(uint32_t fetchdat) +static int +opF7_w_a16(uint32_t fetchdat) { - int32_t low, high; + uint32_t templ, templ2 = 0; + int tempws, tempws2 = 0; + int16_t temps16; + uint16_t src, dst; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + src = getword(); + if (cpu_state.abrt) return 1; - } + setznp16(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(0 - dst); + if (cpu_state.abrt) + return 1; + setsub16(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + break; + case 0x20: /*MUL AX,w*/ + templ = AX * dst; + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x28: /*IMUL AX,w*/ + templ = (int) ((int16_t) AX) * (int) ((int16_t) dst); + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(22); + PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + if (dst) + templ2 = templ / dst; + if (dst && !(templ2 & 0xffff0000)) { + DX = templ % dst; + AX = (templ / dst) & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int) ((DX << 16) | AX); + if (dst) + tempws2 = tempws / (int) ((int16_t) dst); + temps16 = tempws2 & 0xffff; + if ((dst != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) dst); + AX = tempws2 & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(27); + PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 0); - return 0; + default: + x86illegal(); + } + return 0; } -static int opBOUND_l_a32(uint32_t fetchdat) +static int +opF7_w_a32(uint32_t fetchdat) { - int32_t low, high; + uint32_t templ, templ2 = 0; + int tempws, tempws2 = 1; + int16_t temps16; + uint16_t src, dst; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - low = geteal(); - high = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - - if (((int32_t)cpu_state.regs[cpu_reg].l < low) || ((int32_t)cpu_state.regs[cpu_reg].l > high)) - { - x86_int(5); + dst = geteaw(); + if (cpu_state.abrt) + return 1; + switch (rmdat & 0x38) { + case 0x00: /*TEST w*/ + case 0x08: + src = getword(); + if (cpu_state.abrt) return 1; - } + setznp16(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 4, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x10: /*NOT w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x18: /*NEG w*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(0 - dst); + if (cpu_state.abrt) + return 1; + setsub16(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mm); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + break; + case 0x20: /*MUL AX,w*/ + templ = AX * dst; + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x28: /*IMUL AX,w*/ + templ = (int) ((int16_t) AX) * (int) ((int16_t) dst); + AX = templ & 0xFFFF; + DX = templ >> 16; + flags_rebuild(); + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(22); + PREFETCH_RUN(22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x30: /*DIV AX,w*/ + templ = (DX << 16) | AX; + if (dst) + templ2 = templ / dst; + if (dst && !(templ2 & 0xffff0000)) { + DX = templ % dst; + AX = (templ / dst) & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + // fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); + x86_int(0); + return 1; + } + CLOCK_CYCLES((is486 && !cpu_iscyrix) ? 24 : 22); + PREFETCH_RUN((is486 && !cpu_iscyrix) ? 24 : 22, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; + case 0x38: /*IDIV AX,w*/ + tempws = (int) ((DX << 16) | AX); + if (dst) + tempws2 = tempws / (int) ((int16_t) dst); + temps16 = tempws2 & 0xffff; + if ((dst != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) dst); + AX = tempws2 & 0xffff; + if (!cpu_iscyrix) + setznp16(AX); /*Not a Cyrix*/ + } else { + x86_int(0); + return 1; + } + CLOCK_CYCLES(27); + PREFETCH_RUN(27, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + break; - CLOCK_CYCLES(is486 ? 7 : 10); - PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1,1,0,0, 1); - return 0; + default: + x86illegal(); + } + return 0; } - -static int opCLTS(uint32_t fetchdat) +static int +opF7_l_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); + uint64_t temp64; + uint32_t src, dst; + + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + + switch (rmdat & 0x38) { + case 0x00: /*TEST l*/ + case 0x08: + src = getlong(); + if (cpu_state.abrt) return 1; - } - cr0 &= ~8; + setznp32(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(0 - dst); + if (cpu_state.abrt) + return 1; + setsub32(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + break; + case 0x20: /*MUL EAX,l*/ + temp64 = (uint64_t) EAX * (uint64_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (EDX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x28: /*IMUL EAX,l*/ + temp64 = (int64_t) (int32_t) EAX * (int64_t) (int32_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (((int64_t) temp64 >> 31) != 0 && ((int64_t) temp64 >> 31) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(38); + PREFETCH_RUN(38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x30: /*DIV EAX,l*/ + if (divl(dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES((is486) ? 40 : 38); + PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + case 0x38: /*IDIV EAX,l*/ + if (idivl((int32_t) dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES(43); + PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + break; + + default: + x86illegal(); + } + return 0; +} +static int +opF7_l_a32(uint32_t fetchdat) +{ + uint64_t temp64; + uint32_t src, dst; + + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + dst = geteal(); + if (cpu_state.abrt) + return 1; + + switch (rmdat & 0x38) { + case 0x00: /*TEST l*/ + case 0x08: + src = getlong(); + if (cpu_state.abrt) + return 1; + setznp32(src & dst); + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 5, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x10: /*NOT l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(~dst); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x18: /*NEG l*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(0 - dst); + if (cpu_state.abrt) + return 1; + setsub32(0, dst); + CLOCK_CYCLES((cpu_mod == 3) ? timing_rr : timing_mml); + PREFETCH_RUN((cpu_mod == 3) ? timing_rr : timing_mm, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + break; + case 0x20: /*MUL EAX,l*/ + temp64 = (uint64_t) EAX * (uint64_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (EDX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(21); + PREFETCH_RUN(21, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x28: /*IMUL EAX,l*/ + temp64 = (int64_t) (int32_t) EAX * (int64_t) (int32_t) dst; + EAX = temp64 & 0xffffffff; + EDX = temp64 >> 32; + flags_rebuild(); + if (((int64_t) temp64 >> 31) != 0 && ((int64_t) temp64 >> 31) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + CLOCK_CYCLES(38); + PREFETCH_RUN(38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x30: /*DIV EAX,l*/ + if (divl(dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES((is486) ? 40 : 38); + PREFETCH_RUN(is486 ? 40 : 38, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + case 0x38: /*IDIV EAX,l*/ + if (idivl((int32_t) dst)) + return 1; + if (!cpu_iscyrix) + setznp32(EAX); /*Not a Cyrix*/ + CLOCK_CYCLES(43); + PREFETCH_RUN(43, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + break; + + default: + x86illegal(); + } + return 0; +} + +static int +opHLT(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (smi_line) + enter_smm_check(1); + else if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) { + CLOCK_CYCLES_ALWAYS(100); + if (!((cpu_state.flags & I_FLAG) && pic.int_pending)) + cpu_state.pc--; + } else { CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,0,0,0, 0); - return 0; + } + + CPU_BLOCK_END(); + PREFETCH_RUN(100, 1, -1, 0, 0, 0, 0, 0); + + if (hlt_reset_pending) + softresetx86(); + + return 0; } -static int opINVD(uint32_t fetchdat) +static int +opLOCK(uint32_t fetchdat) { - CLOCK_CYCLES(1000); + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 0; + cpu_state.pc++; + + ILLEGAL_ON((fetchdat & 0xff) == 0x90); + + CLOCK_CYCLES(4); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); +} + +static int +opBOUND_w_a16(uint32_t fetchdat) +{ + int16_t low, high; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteaw(); + high = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + + if (((int16_t) cpu_state.regs[cpu_reg].w < low) || ((int16_t) cpu_state.regs[cpu_reg].w > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2, 0, 0, 0, 0); + return 0; +} +static int +opBOUND_w_a32(uint32_t fetchdat) +{ + int16_t low, high; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteaw(); + high = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + + if (((int16_t) cpu_state.regs[cpu_reg].w < low) || ((int16_t) cpu_state.regs[cpu_reg].w > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 2, 0, 0, 0, 1); + return 0; +} + +static int +opBOUND_l_a16(uint32_t fetchdat) +{ + int32_t low, high; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteal(); + high = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + + if (((int32_t) cpu_state.regs[cpu_reg].l < low) || ((int32_t) cpu_state.regs[cpu_reg].l > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1, 1, 0, 0, 0); + return 0; +} +static int +opBOUND_l_a32(uint32_t fetchdat) +{ + int32_t low, high; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + low = geteal(); + high = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + + if (((int32_t) cpu_state.regs[cpu_reg].l < low) || ((int32_t) cpu_state.regs[cpu_reg].l > high)) { + x86_int(5); + return 1; + } + + CLOCK_CYCLES(is486 ? 7 : 10); + PREFETCH_RUN(is486 ? 7 : 10, 2, rmdat, 1, 1, 0, 0, 1); + return 0; +} + +static int +opCLTS(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + cr0 &= ~8; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 0, 0, 0, 0); + return 0; +} + +static int +opINVD(uint32_t fetchdat) +{ + CLOCK_CYCLES(1000); + CPU_BLOCK_END(); + return 0; +} +static int +opWBINVD(uint32_t fetchdat) +{ + CLOCK_CYCLES(10000); + CPU_BLOCK_END(); + return 0; +} + +static int +opLOADALL(uint32_t fetchdat) +{ + if (CPL && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + msw = (msw & 1) | readmemw(0, 0x806); + cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; + flags_extract(); + tr.seg = readmemw(0, 0x816); + cpu_state.pc = readmemw(0, 0x81A); + ldt.seg = readmemw(0, 0x81C); + DS = readmemw(0, 0x81E); + SS = readmemw(0, 0x820); + CS = readmemw(0, 0x822); + ES = readmemw(0, 0x824); + DI = readmemw(0, 0x826); + SI = readmemw(0, 0x828); + BP = readmemw(0, 0x82A); + SP = readmemw(0, 0x82C); + BX = readmemw(0, 0x82E); + DX = readmemw(0, 0x830); + CX = readmemw(0, 0x832); + AX = readmemw(0, 0x834); + es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); + cpu_state.seg_es.access = readmemb(0, 0x839); + cpu_state.seg_es.limit = readmemw(0, 0x83A); + cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); + cpu_state.seg_cs.access = readmemb(0, 0x83F); + cpu_state.seg_cs.limit = readmemw(0, 0x840); + ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); + cpu_state.seg_ss.access = readmemb(0, 0x845); + cpu_state.seg_ss.limit = readmemw(0, 0x846); + if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); + cpu_state.seg_ds.access = readmemb(0, 0x84B); + cpu_state.seg_ds.limit = readmemw(0, 0x84C); + if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); + gdt.limit = readmemw(0, 0x852); + ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); + ldt.access = readmemb(0, 0x857); + ldt.limit = readmemw(0, 0x858); + idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); + idt.limit = readmemw(0, 0x85E); + tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); + tr.access = readmemb(0, 0x863); + tr.limit = readmemw(0, 0x864); + CLOCK_CYCLES(195); + PREFETCH_RUN(195, 1, -1, 51, 0, 0, 0, 0); + return 0; +} + +static void +set_segment_limit(x86seg *s, uint8_t segdat3) +{ + if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ + { + s->limit_high = s->limit; + s->limit_low = 0; + } else { + s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; + } +} + +static void +loadall_load_segment(uint32_t addr, x86seg *s) +{ + uint32_t attrib = readmeml(0, addr); + uint32_t segdat3 = (attrib >> 16) & 0xff; + s->access = (attrib >> 8) & 0xff; + s->ar_high = segdat3; + s->base = readmeml(0, addr + 4); + s->limit = readmeml(0, addr + 8); + + if (s == &cpu_state.seg_cs) + use32 = (segdat3 & 0x40) ? 0x300 : 0; + if (s == &cpu_state.seg_ss) + stack32 = (segdat3 & 0x40) ? 1 : 0; + + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); + if (use32) + cpu_cur_status |= CPU_STATUS_USE32; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; + + set_segment_limit(s, segdat3); + + if (s == &cpu_state.seg_ds) { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + } + if (s == &cpu_state.seg_ss) { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + } +} + +static int +opLOADALL386(uint32_t fetchdat) +{ + uint32_t la_addr = es + EDI; + + cr0 = readmeml(0, la_addr); + cpu_state.flags = readmemw(0, la_addr + 4); + cpu_state.eflags = readmemw(0, la_addr + 6); + flags_extract(); + cpu_state.pc = readmeml(0, la_addr + 8); + EDI = readmeml(0, la_addr + 0xC); + ESI = readmeml(0, la_addr + 0x10); + EBP = readmeml(0, la_addr + 0x14); + ESP = readmeml(0, la_addr + 0x18); + EBX = readmeml(0, la_addr + 0x1C); + EDX = readmeml(0, la_addr + 0x20); + ECX = readmeml(0, la_addr + 0x24); + EAX = readmeml(0, la_addr + 0x28); + dr[6] = readmeml(0, la_addr + 0x2C); + dr[7] = readmeml(0, la_addr + 0x30); + tr.seg = readmemw(0, la_addr + 0x34); + ldt.seg = readmemw(0, la_addr + 0x38); + GS = readmemw(0, la_addr + 0x3C); + FS = readmemw(0, la_addr + 0x40); + DS = readmemw(0, la_addr + 0x44); + SS = readmemw(0, la_addr + 0x48); + CS = readmemw(0, la_addr + 0x4C); + ES = readmemw(0, la_addr + 0x50); + + loadall_load_segment(la_addr + 0x54, &tr); + loadall_load_segment(la_addr + 0x60, &idt); + loadall_load_segment(la_addr + 0x6c, &gdt); + loadall_load_segment(la_addr + 0x78, &ldt); + loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); + loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); + loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); + loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); + loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); + loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); + + if (CPL == 3 && oldcpl != 3) + flushmmucache_cr3(); + oldcpl = CPL; + + CLOCK_CYCLES(350); + return 0; +} + +static int +opCPUID(uint32_t fetchdat) +{ + if (CPUID) { + cpu_CPUID(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opRDMSR(uint32_t fetchdat) +{ + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_RDMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opWRMSR(uint32_t fetchdat) +{ + if (cpu_has_feature(CPU_FEATURE_MSR)) { + cpu_WRMSR(); + CLOCK_CYCLES(9); + return 0; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; +} + +static int +opRSM(uint32_t fetchdat) +{ + if (in_smm) { + leave_smm(); + if (smi_latched) + enter_smm(smm_in_hlt); CPU_BLOCK_END(); return 0; -} -static int opWBINVD(uint32_t fetchdat) -{ - CLOCK_CYCLES(10000); - CPU_BLOCK_END(); - return 0; -} - -static int opLOADALL(uint32_t fetchdat) -{ - if (CPL && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - msw = (msw & 1) | readmemw(0, 0x806); - cpu_state.flags = (readmemw(0, 0x818) & 0xffd5) | 2; - flags_extract(); - tr.seg = readmemw(0, 0x816); - cpu_state.pc = readmemw(0, 0x81A); - ldt.seg = readmemw(0, 0x81C); - DS = readmemw(0, 0x81E); - SS = readmemw(0, 0x820); - CS = readmemw(0, 0x822); - ES = readmemw(0, 0x824); - DI = readmemw(0, 0x826); - SI = readmemw(0, 0x828); - BP = readmemw(0, 0x82A); - SP = readmemw(0, 0x82C); - BX = readmemw(0, 0x82E); - DX = readmemw(0, 0x830); - CX = readmemw(0, 0x832); - AX = readmemw(0, 0x834); - es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); - cpu_state.seg_es.access = readmemb(0, 0x839); - cpu_state.seg_es.limit = readmemw(0, 0x83A); - cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); - cpu_state.seg_cs.access = readmemb(0, 0x83F); - cpu_state.seg_cs.limit = readmemw(0, 0x840); - ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); - cpu_state.seg_ss.access = readmemb(0, 0x845); - cpu_state.seg_ss.limit = readmemw(0, 0x846); - if (cpu_state.seg_ss.base == 0 && cpu_state.seg_ss.limit_low == 0 && cpu_state.seg_ss.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); - cpu_state.seg_ds.access = readmemb(0, 0x84B); - cpu_state.seg_ds.limit = readmemw(0, 0x84C); - if (cpu_state.seg_ds.base == 0 && cpu_state.seg_ds.limit_low == 0 && cpu_state.seg_ds.limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); - gdt.limit = readmemw(0, 0x852); - ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); - ldt.access = readmemb(0, 0x857); - ldt.limit = readmemw(0, 0x858); - idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); - idt.limit = readmemw(0, 0x85E); - tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); - tr.access = readmemb(0, 0x863); - tr.limit = readmemw(0, 0x864); - CLOCK_CYCLES(195); - PREFETCH_RUN(195, 1, -1, 51,0,0,0, 0); - return 0; -} - -static void set_segment_limit(x86seg *s, uint8_t segdat3) -{ - if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ - { - s->limit_high = s->limit; - s->limit_low = 0; - } - else - { - s->limit_high = (segdat3 & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; - } -} - -static void loadall_load_segment(uint32_t addr, x86seg *s) -{ - uint32_t attrib = readmeml(0, addr); - uint32_t segdat3 = (attrib >> 16) & 0xff; - s->access = (attrib >> 8) & 0xff; - s->ar_high = segdat3; - s->base = readmeml(0, addr + 4); - s->limit = readmeml(0, addr + 8); - - if (s == &cpu_state.seg_cs) - use32 = (segdat3 & 0x40) ? 0x300 : 0; - if (s == &cpu_state.seg_ss) - stack32 = (segdat3 & 0x40) ? 1 : 0; - - cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); - if (use32) - cpu_cur_status |= CPU_STATUS_USE32; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - - set_segment_limit(s, segdat3); - - if (s == &cpu_state.seg_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - } - if (s == &cpu_state.seg_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - } -} - -static int opLOADALL386(uint32_t fetchdat) -{ - uint32_t la_addr = es + EDI; - - cr0 = readmeml(0, la_addr); - cpu_state.flags = readmemw(0, la_addr + 4); - cpu_state.eflags = readmemw(0, la_addr + 6); - flags_extract(); - cpu_state.pc = readmeml(0, la_addr + 8); - EDI = readmeml(0, la_addr + 0xC); - ESI = readmeml(0, la_addr + 0x10); - EBP = readmeml(0, la_addr + 0x14); - ESP = readmeml(0, la_addr + 0x18); - EBX = readmeml(0, la_addr + 0x1C); - EDX = readmeml(0, la_addr + 0x20); - ECX = readmeml(0, la_addr + 0x24); - EAX = readmeml(0, la_addr + 0x28); - dr[6] = readmeml(0, la_addr + 0x2C); - dr[7] = readmeml(0, la_addr + 0x30); - tr.seg = readmemw(0, la_addr + 0x34); - ldt.seg = readmemw(0, la_addr + 0x38); - GS = readmemw(0, la_addr + 0x3C); - FS = readmemw(0, la_addr + 0x40); - DS = readmemw(0, la_addr + 0x44); - SS = readmemw(0, la_addr + 0x48); - CS = readmemw(0, la_addr + 0x4C); - ES = readmemw(0, la_addr + 0x50); - - loadall_load_segment(la_addr + 0x54, &tr); - loadall_load_segment(la_addr + 0x60, &idt); - loadall_load_segment(la_addr + 0x6c, &gdt); - loadall_load_segment(la_addr + 0x78, &ldt); - loadall_load_segment(la_addr + 0x84, &cpu_state.seg_gs); - loadall_load_segment(la_addr + 0x90, &cpu_state.seg_fs); - loadall_load_segment(la_addr + 0x9c, &cpu_state.seg_ds); - loadall_load_segment(la_addr + 0xa8, &cpu_state.seg_ss); - loadall_load_segment(la_addr + 0xb4, &cpu_state.seg_cs); - loadall_load_segment(la_addr + 0xc0, &cpu_state.seg_es); - - if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - oldcpl = CPL; - - CLOCK_CYCLES(350); - return 0; -} - -static int opCPUID(uint32_t fetchdat) -{ - if (CPUID) - { - cpu_CPUID(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRDMSR(uint32_t fetchdat) -{ - if (cpu_has_feature(CPU_FEATURE_MSR)) - { - cpu_RDMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opWRMSR(uint32_t fetchdat) -{ - if (cpu_has_feature(CPU_FEATURE_MSR)) - { - cpu_WRMSR(); - CLOCK_CYCLES(9); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; -} - -static int opRSM(uint32_t fetchdat) -{ - if (in_smm) - { - leave_smm(); - if (smi_latched) - enter_smm(smm_in_hlt); - CPU_BLOCK_END(); - return 0; - } - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; + } + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; } diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index f9a7f9357..d270b728f 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -3,47 +3,43 @@ #define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) #define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) -#define MMX_GETSRC() \ - if (cpu_mod == 3) \ - { \ - src = cpu_state.MM[cpu_rm]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - src.q = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; \ - CLOCK_CYCLES(2); \ - } +#define MMX_GETSRC() \ + if (cpu_mod == 3) { \ + src = cpu_state.MM[cpu_rm]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + src.q = readmemq(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 1; \ + CLOCK_CYCLES(2); \ + } -#define MMX_ENTER() \ - if (!cpu_has_feature(CPU_FEATURE_MMX)) \ - { \ - cpu_state.pc = cpu_state.oldpc; \ - x86illegal(); \ - return 1; \ - } \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ - x87_set_mmx() +#define MMX_ENTER() \ + if (!cpu_has_feature(CPU_FEATURE_MMX)) { \ + cpu_state.pc = cpu_state.oldpc; \ + x86illegal(); \ + return 1; \ + } \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ + x87_set_mmx() -static int opEMMS(uint32_t fetchdat) +static int +opEMMS(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_MMX)) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - x87_emms(); - CLOCK_CYCLES(100); /*Guess*/ - return 0; + if (!cpu_has_feature(CPU_FEATURE_MMX)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } + x87_emms(); + CLOCK_CYCLES(100); /*Guess*/ + return 0; } diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index afa8aa383..e473f8ec5 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,631 +1,660 @@ -static int opPADDB_a16(uint32_t fetchdat) +static int +opPADDB_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + + return 0; +} +static int +opPADDB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + + return 0; +} + +static int +opPADDW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + + return 0; +} +static int +opPADDW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + + return 0; +} + +static int +opPADDD_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + + return 0; +} +static int +opPADDD_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + + return 0; +} + +static int +opPADDSB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + + return 0; +} +static int +opPADDSB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + + return 0; +} + +static int +opPADDUSB_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + + return 0; +} +static int +opPADDUSB_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + + return 0; +} + +static int +opPADDSW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + + return 0; +} +static int +opPADDSW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + + return 0; +} + +static int +opPADDUSW_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + + return 0; +} +static int +opPADDUSW_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + + return 0; +} + +static int +opPMADDWD_a16(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSRC(); + + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + + return 0; +} +static int +opPMADDWD_a32(uint32_t fetchdat) +{ + MMX_REG src; + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSRC(); + + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + + return 0; +} + +static int +opPMULLW_a16(uint32_t fetchdat) +{ + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDB_a32(uint32_t fetchdat) +static int +opPMULLW_a32(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDW_a16(uint32_t fetchdat) +static int +opPMULHW_a16(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDW_a32(uint32_t fetchdat) +static int +opPMULHW_a32(uint32_t fetchdat) { + MMX_ENTER(); + + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { MMX_REG src; - MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } + return 0; } -static int opPADDD_a16(uint32_t fetchdat) +static int +opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - return 0; + return 0; } -static int opPADDD_a32(uint32_t fetchdat) +static int +opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - return 0; + return 0; } -static int opPADDSB_a16(uint32_t fetchdat) +static int +opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - return 0; + return 0; } -static int opPADDSB_a32(uint32_t fetchdat) +static int +opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - return 0; + return 0; } -static int opPADDUSB_a16(uint32_t fetchdat) +static int +opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } -static int opPADDUSB_a32(uint32_t fetchdat) +static int +opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - return 0; + return 0; } -static int opPADDSW_a16(uint32_t fetchdat) +static int +opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + pclog("opPSUBSB_a16(%08X)\n", fetchdat); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - return 0; + return 0; } -static int opPADDSW_a32(uint32_t fetchdat) +static int +opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + pclog("opPSUBSB_a32(%08X)\n", fetchdat); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - return 0; + return 0; } -static int opPADDUSW_a16(uint32_t fetchdat) +static int +opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - return 0; + return 0; } -static int opPADDUSW_a32(uint32_t fetchdat) +static int +opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - return 0; + return 0; } -static int opPMADDWD_a16(uint32_t fetchdat) +static int +opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; + return 0; } -static int opPMADDWD_a32(uint32_t fetchdat) +static int +opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) + ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) + ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]); - - return 0; + return 0; } - -static int opPMULLW_a16(uint32_t fetchdat) +static int +opPSUBUSW_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; + fetch_ea_16(fetchdat); + MMX_GETSRC(); - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + + return 0; } -static int opPMULLW_a32(uint32_t fetchdat) +static int +opPSUBUSW_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; + fetch_ea_32(fetchdat); + MMX_GETSRC(); - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPMULHW_a16(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} -static int opPMULHW_a32(uint32_t fetchdat) -{ - MMX_ENTER(); - - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } - else - { - MMX_REG src; - - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t)cpu_state.MM[cpu_reg].sw[0] * (int32_t)src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t)cpu_state.MM[cpu_reg].sw[1] * (int32_t)src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t)cpu_state.MM[cpu_reg].sw[2] * (int32_t)src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t)cpu_state.MM[cpu_reg].sw[3] * (int32_t)src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } - return 0; -} - -static int opPSUBB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} -static int opPSUBB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; - - return 0; -} - -static int opPSUBW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} -static int opPSUBW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; - - return 0; -} - -static int opPSUBD_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} -static int opPSUBD_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; - - return 0; -} - -static int opPSUBSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - pclog("opPSUBSB_a16(%08X)\n", fetchdat); - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} -static int opPSUBSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - pclog("opPSUBSB_a32(%08X)\n", fetchdat); - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); - - return 0; -} - -static int opPSUBUSB_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} -static int opPSUBUSB_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); - - return 0; -} - -static int opPSUBSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} -static int opPSUBSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); - - return 0; -} - -static int opPSUBUSW_a16(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; -} -static int opPSUBUSW_a32(uint32_t fetchdat) -{ - MMX_REG src; - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSRC(); - - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); - - return 0; + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + + return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index a07d8d0a8..40ae66a9c 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,205 +1,217 @@ -static int opPCMPEQB_a16(uint32_t fetchdat) +static int +opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPEQB_a32(uint32_t fetchdat) +static int +opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPGTB_a16(uint32_t fetchdat) +static int +opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPGTB_a32(uint32_t fetchdat) +static int +opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; - return 0; + return 0; } -static int opPCMPEQW_a16(uint32_t fetchdat) +static int +opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPEQW_a32(uint32_t fetchdat) +static int +opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPGTW_a16(uint32_t fetchdat) +static int +opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPGTW_a32(uint32_t fetchdat) +static int +opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; - return 0; + return 0; } -static int opPCMPEQD_a16(uint32_t fetchdat) +static int +opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPEQD_a32(uint32_t fetchdat) +static int +opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPGTD_a16(uint32_t fetchdat) +static int +opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - return 0; + return 0; } -static int opPCMPGTD_a32(uint32_t fetchdat) +static int +opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; - return 0; + return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index e3f1d9145..c22c820c1 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,91 +1,99 @@ -static int opPAND_a16(uint32_t fetchdat) +static int +opPAND_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } -static int opPAND_a32(uint32_t fetchdat) +static int +opPAND_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; - return 0; + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } -static int opPANDN_a16(uint32_t fetchdat) +static int +opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } -static int opPANDN_a32(uint32_t fetchdat) +static int +opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; - return 0; + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } -static int opPOR_a16(uint32_t fetchdat) +static int +opPOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } -static int opPOR_a32(uint32_t fetchdat) +static int +opPOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; - return 0; + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } -static int opPXOR_a16(uint32_t fetchdat) +static int +opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } -static int opPXOR_a32(uint32_t fetchdat) +static int +opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; - return 0; + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index fe06525b7..bb51573e6 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -1,217 +1,217 @@ -static int opMOVD_l_mm_a16(uint32_t fetchdat) +static int +opMOVD_l_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_l_mm_a32(uint32_t fetchdat) +static int +opMOVD_l_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } - else - { - uint32_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + uint32_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a16(uint32_t fetchdat) +static int +opMOVD_mm_l_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a32(uint32_t fetchdat) +static int +opMOVD_mm_l_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) /*Cyrix maps both MOVD and SMINT to the same opcode*/ -static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) +static int +opMOVD_mm_l_a16_cx(uint32_t fetchdat) { - if (in_smm) - return opSMINT(fetchdat); + if (in_smm) + return opSMINT(fetchdat); - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) +static int +opMOVD_mm_l_a32_cx(uint32_t fetchdat) { - if (in_smm) - return opSMINT(fetchdat); + if (in_smm) + return opSMINT(fetchdat); - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } #endif -static int opMOVQ_q_mm_a16(uint32_t fetchdat) +static int +opMOVQ_q_mm_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_q_mm_a32(uint32_t fetchdat) +static int +opMOVQ_q_mm_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } - else - { - uint64_t dst; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + uint64_t dst; - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); - } - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_mm_q_a16(uint32_t fetchdat) +static int +opMOVQ_mm_q_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } -static int opMOVQ_mm_q_a32(uint32_t fetchdat) +static int +opMOVQ_mm_q_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); if (cpu_state.abrt) return 1; - CLOCK_CYCLES(2); - } - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } + return 0; } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index e12d1b448..f0180db91 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -1,326 +1,342 @@ -static int opPUNPCKLDQ_a16(uint32_t fetchdat) +static int +opPUNPCKLDQ_a16(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opPUNPCKLDQ_a32(uint32_t fetchdat) +static int +opPUNPCKLDQ_a32(uint32_t fetchdat) { - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } - else - { - uint32_t src; + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + uint32_t src; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].l[1] = src; + SEG_CHECK_READ(cpu_state.ea_seg); + src = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = src; - CLOCK_CYCLES(2); - } - return 0; + CLOCK_CYCLES(2); + } + return 0; } -static int opPUNPCKHDQ_a16(uint32_t fetchdat) +static int +opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; - return 0; + return 0; } -static int opPUNPCKHDQ_a32(uint32_t fetchdat) +static int +opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; - return 0; + return 0; } -static int opPUNPCKLBW_a16(uint32_t fetchdat) +static int +opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - return 0; + return 0; } -static int opPUNPCKLBW_a32(uint32_t fetchdat) +static int +opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - return 0; + return 0; } -static int opPUNPCKHBW_a16(uint32_t fetchdat) +static int +opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; - return 0; + return 0; } -static int opPUNPCKHBW_a32(uint32_t fetchdat) +static int +opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; - return 0; + return 0; } -static int opPUNPCKLWD_a16(uint32_t fetchdat) +static int +opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - return 0; + return 0; } -static int opPUNPCKLWD_a32(uint32_t fetchdat) +static int +opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - return 0; + return 0; } -static int opPUNPCKHWD_a16(uint32_t fetchdat) +static int +opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); + fetch_ea_16(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; - return 0; + return 0; } -static int opPUNPCKHWD_a32(uint32_t fetchdat) +static int +opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; - MMX_ENTER(); + MMX_REG src; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); + fetch_ea_32(fetchdat); + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; - return 0; + return 0; } -static int opPACKSSWB_a16(uint32_t fetchdat) +static int +opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - return 0; + return 0; } -static int opPACKSSWB_a32(uint32_t fetchdat) +static int +opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); - return 0; + return 0; } -static int opPACKUSWB_a16(uint32_t fetchdat) +static int +opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - return 0; + return 0; } -static int opPACKUSWB_a32(uint32_t fetchdat) +static int +opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); - return 0; + return 0; } -static int opPACKSSDW_a16(uint32_t fetchdat) +static int +opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_16(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - return 0; + return 0; } -static int opPACKSSDW_a32(uint32_t fetchdat) +static int +opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; - MMX_ENTER(); + MMX_REG src, dst; + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; + fetch_ea_32(fetchdat); + MMX_GETSRC(); + dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); - return 0; + return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index df8d75cf8..c9ddc9b93 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -1,450 +1,453 @@ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) \ - { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } \ - else \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - shift = readmemb(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; \ - CLOCK_CYCLES(2); \ - } +#define MMX_GETSHIFT() \ + if (cpu_mod == 3) { \ + shift = cpu_state.MM[cpu_rm].b[0]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 0; \ + CLOCK_CYCLES(2); \ + } -static int opPSxxW_imm(uint32_t fetchdat) +static int +opPSxxW_imm(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - cpu_state.pc += 2; - MMX_ENTER(); + cpu_state.pc += 2; + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; - } - break; - case 0x20: /*PSRAW*/ - if (shift > 15) - shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; - } - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } - - CLOCK_CYCLES(1); - return 0; -} - -static int opPSLLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} -static int opPSLLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } - - return 0; -} - -static int opPSRLW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} -static int opPSRLW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } - - return 0; -} - -static int opPSRAW_a16(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) + switch (op) { + case 0x10: /*PSRLW*/ + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] >>= shift; + cpu_state.MM[reg].w[1] >>= shift; + cpu_state.MM[reg].w[2] >>= shift; + cpu_state.MM[reg].w[3] >>= shift; + } + break; + case 0x20: /*PSRAW*/ + if (shift > 15) shift = 15; + cpu_state.MM[reg].sw[0] >>= shift; + cpu_state.MM[reg].sw[1] >>= shift; + cpu_state.MM[reg].sw[2] >>= shift; + cpu_state.MM[reg].sw[3] >>= shift; + break; + case 0x30: /*PSLLW*/ + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] <<= shift; + cpu_state.MM[reg].w[1] <<= shift; + cpu_state.MM[reg].w[2] <<= shift; + cpu_state.MM[reg].w[3] <<= shift; + } + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; -} -static int opPSRAW_a32(uint32_t fetchdat) -{ - int shift; - - MMX_ENTER(); - - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; - - return 0; + CLOCK_CYCLES(1); + return 0; } -static int opPSxxD_imm(uint32_t fetchdat) +static int +opPSLLW_a16(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int shift; - cpu_state.pc += 2; - MMX_ENTER(); + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; - } - break; - case 0x20: /*PSRAD*/ - if (shift > 31) - shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; - break; - case 0x30: /*PSLLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else - { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; - } - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - CLOCK_CYCLES(1); - return 0; + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } + + return 0; +} +static int +opPSLLW_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } + + return 0; } -static int opPSLLD_a16(uint32_t fetchdat) +static int +opPSRLW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } - return 0; + return 0; } -static int opPSLLD_a32(uint32_t fetchdat) +static int +opPSRLW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } - return 0; + return 0; } -static int opPSRLD_a16(uint32_t fetchdat) +static int +opPSRAW_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } + if (shift > 15) + shift = 15; - return 0; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + + return 0; } -static int opPSRLD_a32(uint32_t fetchdat) +static int +opPSRAW_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else - { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } + if (shift > 15) + shift = 15; - return 0; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + + return 0; } -static int opPSRAD_a16(uint32_t fetchdat) +static int +opPSxxD_imm(uint32_t fetchdat) { - int shift; + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; - MMX_ENTER(); + cpu_state.pc += 2; + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); - - if (shift > 31) + switch (op) { + case 0x10: /*PSRLD*/ + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] >>= shift; + cpu_state.MM[reg].l[1] >>= shift; + } + break; + case 0x20: /*PSRAD*/ + if (shift > 31) shift = 31; + cpu_state.MM[reg].sl[0] >>= shift; + cpu_state.MM[reg].sl[1] >>= shift; + break; + case 0x30: /*PSLLD*/ + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] <<= shift; + cpu_state.MM[reg].l[1] <<= shift; + } + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; + CLOCK_CYCLES(1); + return 0; } -static int opPSRAD_a32(uint32_t fetchdat) + +static int +opPSLLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 31) - shift = 31; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; - - return 0; + return 0; } - -static int opPSxxQ_imm(uint32_t fetchdat) +static int +opPSLLD_a32(uint32_t fetchdat) { - int reg = fetchdat & 7; - int op = fetchdat & 0x38; - int shift = (fetchdat >> 8) & 0xff; + int shift; - cpu_state.pc += 2; - MMX_ENTER(); + MMX_ENTER(); - switch (op) - { - case 0x10: /*PSRLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q >>= shift; - break; - case 0x20: /*PSRAW*/ - if (shift > 63) - shift = 63; - cpu_state.MM[reg].sq >>= shift; - break; - case 0x30: /*PSLLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q <<= shift; - break; - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 0; - } + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - CLOCK_CYCLES(1); - return 0; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } + + return 0; } -static int opPSLLQ_a16(uint32_t fetchdat) +static int +opPSRLD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } - return 0; + return 0; } -static int opPSLLQ_a32(uint32_t fetchdat) +static int +opPSRLD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } - return 0; + return 0; } -static int opPSRLQ_a16(uint32_t fetchdat) +static int +opPSRAD_a16(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 31) + shift = 31; - return 0; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + + return 0; } -static int opPSRLQ_a32(uint32_t fetchdat) +static int +opPSRAD_a32(uint32_t fetchdat) { - int shift; + int shift; - MMX_ENTER(); + MMX_ENTER(); - fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + if (shift > 31) + shift = 31; - return 0; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + + return 0; +} + +static int +opPSxxQ_imm(uint32_t fetchdat) +{ + int reg = fetchdat & 7; + int op = fetchdat & 0x38; + int shift = (fetchdat >> 8) & 0xff; + + cpu_state.pc += 2; + MMX_ENTER(); + + switch (op) { + case 0x10: /*PSRLW*/ + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q >>= shift; + break; + case 0x20: /*PSRAW*/ + if (shift > 63) + shift = 63; + cpu_state.MM[reg].sq >>= shift; + break; + case 0x30: /*PSLLW*/ + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q <<= shift; + break; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 0; + } + + CLOCK_CYCLES(1); + return 0; +} + +static int +opPSLLQ_a16(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + + return 0; +} +static int +opPSLLQ_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + + return 0; +} + +static int +opPSRLQ_a16(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_16(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + + return 0; +} +static int +opPSRLQ_a32(uint32_t fetchdat) +{ + int shift; + + MMX_ENTER(); + + fetch_ea_32(fetchdat); + MMX_GETSHIFT(); + + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + + return 0; } diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index e7d5247d1..33a8a44c0 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -1,770 +1,851 @@ -static int opMOV_AL_imm(uint32_t fetchdat) +static int +opMOV_AL_imm(uint32_t fetchdat) { - AL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + AL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_AH_imm(uint32_t fetchdat) +static int +opMOV_AH_imm(uint32_t fetchdat) { - AH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + AH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BL_imm(uint32_t fetchdat) +static int +opMOV_BL_imm(uint32_t fetchdat) { - BL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + BL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BH_imm(uint32_t fetchdat) +static int +opMOV_BH_imm(uint32_t fetchdat) { - BH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + BH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CL_imm(uint32_t fetchdat) +static int +opMOV_CL_imm(uint32_t fetchdat) { - CL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + CL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CH_imm(uint32_t fetchdat) +static int +opMOV_CH_imm(uint32_t fetchdat) { - CH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + CH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DL_imm(uint32_t fetchdat) +static int +opMOV_DL_imm(uint32_t fetchdat) { - DL = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + DL = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DH_imm(uint32_t fetchdat) +static int +opMOV_DH_imm(uint32_t fetchdat) { - DH = getbytef(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, -1, 0,0,0,0, 0); - return 0; + DH = getbytef(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_AX_imm(uint32_t fetchdat) +static int +opMOV_AX_imm(uint32_t fetchdat) { - AX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + AX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BX_imm(uint32_t fetchdat) +static int +opMOV_BX_imm(uint32_t fetchdat) { - BX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + BX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CX_imm(uint32_t fetchdat) +static int +opMOV_CX_imm(uint32_t fetchdat) { - CX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + CX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DX_imm(uint32_t fetchdat) +static int +opMOV_DX_imm(uint32_t fetchdat) { - DX = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + DX = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_SI_imm(uint32_t fetchdat) +static int +opMOV_SI_imm(uint32_t fetchdat) { - SI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + SI = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DI_imm(uint32_t fetchdat) +static int +opMOV_DI_imm(uint32_t fetchdat) { - DI = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + DI = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_BP_imm(uint32_t fetchdat) +static int +opMOV_BP_imm(uint32_t fetchdat) { - BP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + BP = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_SP_imm(uint32_t fetchdat) +static int +opMOV_SP_imm(uint32_t fetchdat) { - SP = getwordf(); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, -1, 0,0,0,0, 0); - return 0; + SP = getwordf(); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EAX_imm(uint32_t fetchdat) +static int +opMOV_EAX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EAX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EAX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EBX_imm(uint32_t fetchdat) +static int +opMOV_EBX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EBX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ECX_imm(uint32_t fetchdat) +static int +opMOV_ECX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ECX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ECX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EDX_imm(uint32_t fetchdat) +static int +opMOV_EDX_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDX = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EDX = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ESI_imm(uint32_t fetchdat) +static int +opMOV_ESI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ESI = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EDI_imm(uint32_t fetchdat) +static int +opMOV_EDI_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EDI = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EDI = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_EBP_imm(uint32_t fetchdat) +static int +opMOV_EBP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - EBP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + EBP = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_ESP_imm(uint32_t fetchdat) +static int +opMOV_ESP_imm(uint32_t fetchdat) { - uint32_t templ = getlong(); if (cpu_state.abrt) return 1; - ESP = templ; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 5, -1, 0,0,0,0, 0); - return 0; + uint32_t templ = getlong(); + if (cpu_state.abrt) + return 1; + ESP = templ; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 5, -1, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_b_imm_a16(uint32_t fetchdat) +static int +opMOV_b_imm_a16(uint32_t fetchdat) { - uint8_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); + uint8_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = readmemb(cs, cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + seteab(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_b_imm_a32(uint32_t fetchdat) +{ + uint8_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getbyte(); + if (cpu_state.abrt) + return 1; + seteab(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 3, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_w_imm_a16(uint32_t fetchdat) +{ + uint16_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getword(); + if (cpu_state.abrt) + return 1; + seteaw(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 4, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_w_imm_a32(uint32_t fetchdat) +{ + uint16_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getword(); + if (cpu_state.abrt) + return 1; + seteaw(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 4, rmdat, 0, 0, (cpu_mod == 3) ? 1 : 0, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_l_imm_a16(uint32_t fetchdat) +{ + uint32_t temp; + fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getlong(); + if (cpu_state.abrt) + return 1; + seteal(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 6, rmdat, 0, 0, 0, (cpu_mod == 3) ? 1 : 0, 0); + return cpu_state.abrt; +} +static int +opMOV_l_imm_a32(uint32_t fetchdat) +{ + uint32_t temp; + fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = getlong(); + if (cpu_state.abrt) + return 1; + seteal(temp); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 6, rmdat, 0, 0, 0, (cpu_mod == 3) ? 1 : 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_AL_a16(uint32_t fetchdat) +{ + uint8_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opMOV_AL_a32(uint32_t fetchdat) +{ + uint8_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 1, 0, 0, 0, 1); + return 0; +} +static int +opMOV_AX_a16(uint32_t fetchdat) +{ + uint16_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); + temp = readmemw(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opMOV_AX_a32(uint32_t fetchdat) +{ + uint16_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 1); + temp = readmemw(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 1, 0, 0, 0, 1); + return 0; +} +static int +opMOV_EAX_a16(uint32_t fetchdat) +{ + uint32_t temp; + uint16_t addr = getwordf(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); + temp = readmeml(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + EAX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 3, -1, 0, 1, 0, 0, 0); + return 0; +} +static int +opMOV_EAX_a32(uint32_t fetchdat) +{ + uint32_t temp; + uint32_t addr = getlong(); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, addr, addr + 3); + temp = readmeml(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + EAX = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 5, -1, 0, 1, 0, 0, 1); + return 0; +} + +static int +opMOV_a16_AL(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); + writememb(cpu_state.ea_seg->base, addr, AL); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_AL(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); + writememb(cpu_state.ea_seg->base, addr, AL); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 1, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_a16_AX(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); + writememw(cpu_state.ea_seg->base, addr, AX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_AX(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); + writememw(cpu_state.ea_seg->base, addr, AX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 1, 0, 1); + return cpu_state.abrt; +} +static int +opMOV_a16_EAX(uint32_t fetchdat) +{ + uint16_t addr = getwordf(); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); + writememl(cpu_state.ea_seg->base, addr, EAX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; +} +static int +opMOV_a32_EAX(uint32_t fetchdat) +{ + uint32_t addr = getlong(); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); + writememl(cpu_state.ea_seg->base, addr, EAX); + CLOCK_CYCLES((is486) ? 1 : 2); + PREFETCH_RUN(2, 5, -1, 0, 0, 0, 1, 1); + return cpu_state.abrt; +} + +static int +opLEA_w_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opLEA_w_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opLEA_l_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opLEA_l_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + cpu_state.regs[cpu_reg].l = cpu_state.eaaddr; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opXLAT_a16(uint32_t fetchdat) +{ + uint32_t addr = (BX + AL) & 0xFFFF; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; +} +static int +opXLAT_a32(uint32_t fetchdat) +{ + uint32_t addr = EBX + AL; + uint8_t temp; + + SEG_CHECK_READ(cpu_state.ea_seg); + temp = readmemb(cpu_state.ea_seg->base, addr); + if (cpu_state.abrt) + return 1; + AL = temp; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_b_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_rm, getr8(cpu_reg)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; - seteab(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; + seteab(getr8(cpu_reg)); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 0); + } + return cpu_state.abrt; } -static int opMOV_b_imm_a32(uint32_t fetchdat) +static int +opMOV_b_r_a32(uint32_t fetchdat) { - uint8_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getbyte(); if (cpu_state.abrt) return 1; - seteab(temp); + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_rm, getr8(cpu_reg)); CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 3, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteab(getr8(cpu_reg)); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 1); + } + return cpu_state.abrt; +} +static int +opMOV_w_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.regs[cpu_reg].w); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 0); + } + return cpu_state.abrt; +} +static int +opMOV_w_r_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.regs[cpu_reg].w); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 1, 0, 1); + } + return cpu_state.abrt; +} +static int +opMOV_l_r_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(cpu_state.regs[cpu_reg].l); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 0); + } + return cpu_state.abrt; +} +static int +opMOV_l_r_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(cpu_state.regs[cpu_reg].l); + CLOCK_CYCLES(is486 ? 1 : 2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, 0, 1, 1); + } + return cpu_state.abrt; } -static int opMOV_w_imm_a16(uint32_t fetchdat) +static int +opMOV_r_b_a16(uint32_t fetchdat) { + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_reg, getr8(cpu_rm)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + temp = geteab(); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 0); + } + return 0; +} +static int +opMOV_r_b_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + setr8(cpu_reg, getr8(cpu_rm)); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { + uint8_t temp; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); + temp = geteab(); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 1); + } + return 0; +} +static int +opMOV_r_w_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { uint16_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 0); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 0); + } + return 0; } -static int opMOV_w_imm_a32(uint32_t fetchdat) +static int +opMOV_r_w_a32(uint32_t fetchdat) { + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { uint16_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getword(); if (cpu_state.abrt) return 1; - seteaw(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 4, rmdat, 0,0,(cpu_mod == 3) ? 1:0,0, 1); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((is486) ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 1, 0, 0, 0, 1); + } + return 0; } -static int opMOV_l_imm_a16(uint32_t fetchdat) +static int +opMOV_r_l_a16(uint32_t fetchdat) { + fetch_ea_16(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + } else { uint32_t temp; - fetch_ea_16(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 0); - return cpu_state.abrt; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + temp = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 0); + } + return 0; } -static int opMOV_l_imm_a32(uint32_t fetchdat) +static int +opMOV_r_l_a32(uint32_t fetchdat) { + fetch_ea_32(fetchdat); + if (cpu_mod == 3) { + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 1); + } else { uint32_t temp; - fetch_ea_32(fetchdat); - ILLEGAL_ON((rmdat & 0x38) != 0); - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = getlong(); if (cpu_state.abrt) return 1; - seteal(temp); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 6, rmdat, 0,0,0,(cpu_mod == 3) ? 1:0, 1); - return cpu_state.abrt; -} - - -static int opMOV_AL_a16(uint32_t fetchdat) -{ - uint8_t temp; - uint16_t addr = getwordf(); SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AL_a32(uint32_t fetchdat) -{ - uint8_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_AX_a16(uint32_t fetchdat) -{ - uint16_t temp; - uint16_t addr = getwordf(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr + 1UL); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); - return 0; -} -static int opMOV_AX_a32(uint32_t fetchdat) -{ - uint16_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+1); - temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); - return 0; -} -static int opMOV_EAX_a16(uint32_t fetchdat) -{ - uint32_t temp; - uint16_t addr = getwordf(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr + 3UL); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 3, -1, 0,1,0,0, 0); - return 0; -} -static int opMOV_EAX_a32(uint32_t fetchdat) -{ - uint32_t temp; - uint32_t addr = getlong(); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, addr, addr+3); - temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - EAX = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 5, -1, 0,1,0,0, 1); - return 0; + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + temp = geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES(is486 ? 1 : 4); + PREFETCH_RUN(4, 2, rmdat, 0, 1, 0, 0, 1); + } + return 0; } -static int opMOV_a16_AL(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AL(uint32_t fetchdat) -{ - uint32_t addr = getlong(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr); - writememb(cpu_state.ea_seg->base, addr, AL); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_AX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1UL); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; -} -static int opMOV_a32_AX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 1); - writememw(cpu_state.ea_seg->base, addr, AX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,1,0, 1); - return cpu_state.abrt; -} -static int opMOV_a16_EAX(uint32_t fetchdat) -{ - uint16_t addr = getwordf(); - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3UL); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; -} -static int opMOV_a32_EAX(uint32_t fetchdat) -{ - uint32_t addr = getlong(); if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, addr, addr + 3); - writememl(cpu_state.ea_seg->base, addr, EAX); - CLOCK_CYCLES((is486) ? 1 : 2); - PREFETCH_RUN(2, 5, -1, 0,0,0,1, 1); - return cpu_state.abrt; -} - - -static int opLEA_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opLEA_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].l = cpu_state.eaaddr & 0xffff; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opLEA_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - cpu_state.regs[cpu_reg].l = cpu_state.eaaddr; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - return 0; -} - - - -static int opXLAT_a16(uint32_t fetchdat) -{ - uint32_t addr = (BX + AL)&0xFFFF; - uint8_t temp; - - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; -} -static int opXLAT_a32(uint32_t fetchdat) -{ - uint32_t addr = EBX + AL; - uint8_t temp; - - SEG_CHECK_READ(cpu_state.ea_seg); - temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; - AL = temp; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; -} - -static int opMOV_b_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_b_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_rm, getr8(cpu_reg)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteab(getr8(cpu_reg)); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 0); - } - return cpu_state.abrt; -} -static int opMOV_w_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].w = cpu_state.regs[cpu_reg].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.regs[cpu_reg].w); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,1,0, 1); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 0); - } - return cpu_state.abrt; -} -static int opMOV_l_r_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_rm].l = cpu_state.regs[cpu_reg].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(cpu_state.regs[cpu_reg].l); - CLOCK_CYCLES(is486 ? 1 : 2); - PREFETCH_RUN(2, 2, rmdat, 0,0,0,1, 1); - } - return cpu_state.abrt; -} - -static int opMOV_r_b_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_b_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - setr8(cpu_reg, getr8(cpu_rm)); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); - temp = geteab(); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_w_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 0); - } - return 0; -} -static int opMOV_r_w_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((is486) ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 1,0,0,0, 1); - } - return 0; -} -static int opMOV_r_l_a16(uint32_t fetchdat) -{ - fetch_ea_16(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - } - else - { - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 0); - } - return 0; -} -static int opMOV_r_l_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod == 3) - { - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); - } - else - { - uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); - temp = geteal(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES(is486 ? 1 : 4); - PREFETCH_RUN(4, 2, rmdat, 0,1,0,0, 1); - } - return 0; -} - -#define opCMOV(condition) \ - static int opCMOV ## condition ## _w_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _w_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ - else \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+1); \ - temp = geteaw(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } \ - static int opCMOV ## condition ## _l_a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cond_ ## condition) \ - { \ - if (cpu_mod == 3) \ - cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ - else \ - { \ - uint32_t temp; \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr+3); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - temp = geteal(); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = temp; \ - } \ - } \ - CLOCK_CYCLES(1); \ - return 0; \ - } +#define opCMOV(condition) \ + static int opCMOV##condition##_w_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_w_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].w = cpu_state.regs[cpu_rm].w; \ + else { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 1); \ + temp = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } \ + static int opCMOV##condition##_l_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cond_##condition) { \ + if (cpu_mod == 3) \ + cpu_state.regs[cpu_reg].l = cpu_state.regs[cpu_rm].l; \ + else { \ + uint32_t temp; \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + temp = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = temp; \ + } \ + } \ + CLOCK_CYCLES(1); \ + return 0; \ + } opCMOV(O) opCMOV(NO) diff --git a/src/cpu/x86_ops_mov_ctrl.h b/src/cpu/x86_ops_mov_ctrl.h index 0d973338e..0cfa38095 100644 --- a/src/cpu/x86_ops_mov_ctrl.h +++ b/src/cpu/x86_ops_mov_ctrl.h @@ -1,368 +1,362 @@ -static int opMOV_r_CRx_a16(uint32_t fetchdat) +static int +opMOV_r_CRx_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486 || isibm486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - else { - if (is386) - cpu_state.regs[cpu_rm].l |=0x7fffffe0; - else - cpu_state.regs[cpu_rm].l |=0x7ffffff0; - } - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_CRx_a32(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - cpu_state.regs[cpu_rm].l = cr0; - if (is486 || isibm486) - cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ - else { - if (is386) - cpu_state.regs[cpu_rm].l |=0x7fffffe0; - else - cpu_state.regs[cpu_rm].l |=0x7ffffff0; - } - break; - case 2: - cpu_state.regs[cpu_rm].l = cr2; - break; - case 3: - cpu_state.regs[cpu_rm].l = cr3; - break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - cpu_state.regs[cpu_rm].l = cr4; - break; - } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_r_DRx_a16(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_DRx_a32(uint32_t fetchdat) -{ - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static int opMOV_CRx_r_a16(uint32_t fetchdat) -{ - uint32_t old_cr0 = cr0; - - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - fetch_ea_16(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - /* Make sure CPL = 0 when switching from real mode to protected mode. */ - if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) - cpu_state.seg_cs.access &= 0x9f; - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (hascache && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; else - cpu_cur_status &= ~CPU_STATUS_PMODE; + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_CRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + cpu_state.regs[cpu_rm].l = cr0; + if (is486 || isibm486) + cpu_state.regs[cpu_rm].l |= 0x10; /*ET hardwired on 486*/ + else { + if (is386) + cpu_state.regs[cpu_rm].l |= 0x7fffffe0; + else + cpu_state.regs[cpu_rm].l |= 0x7ffffff0; + } + break; + case 2: + cpu_state.regs[cpu_rm].l = cr2; + break; + case 3: + cpu_state.regs[cpu_rm].l = cr3; + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + cpu_state.regs[cpu_rm].l = cr4; break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; + } + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_r_DRx_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_DRx_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + cpu_state.regs[cpu_rm].l = dr[cpu_reg] | (cpu_reg == 6 ? 0xffff0ff0u : 0); + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_CRx_r_a16(uint32_t fetchdat) +{ + uint32_t old_cr0 = cr0; + + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) - flushmmucache(); - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; - break; - } + } - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 0); - return 0; + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_CRx_r_a32(uint32_t fetchdat) +static int +opMOV_CRx_r_a32(uint32_t fetchdat) { - uint32_t old_cr0 = cr0; + uint32_t old_cr0 = cr0; - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - fetch_ea_32(fetchdat); - switch (cpu_reg) - { - case 0: - if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) - flushmmucache(); - /* Make sure CPL = 0 when switching from real mode to protected mode. */ - if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) - cpu_state.seg_cs.access &= 0x9f; - cr0 = cpu_state.regs[cpu_rm].l; - if (cpu_16bitbus) - cr0 |= 0x10; - if (!(cr0 & 0x80000000)) - mmu_perm=4; - if (hascache && !(cr0 & (1 << 30))) - cpu_cache_int_enabled = 1; - else - cpu_cache_int_enabled = 0; - if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) - cpu_update_waitstates(); - if (cr0 & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - break; - case 2: - cr2 = cpu_state.regs[cpu_rm].l; - break; - case 3: - cr3 = cpu_state.regs[cpu_rm].l; + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + switch (cpu_reg) { + case 0: + if ((cpu_state.regs[cpu_rm].l ^ cr0) & 0x80000001) flushmmucache(); + /* Make sure CPL = 0 when switching from real mode to protected mode. */ + if ((cpu_state.regs[cpu_rm].l & 0x01) && !(cr0 & 0x01)) + cpu_state.seg_cs.access &= 0x9f; + cr0 = cpu_state.regs[cpu_rm].l; + if (cpu_16bitbus) + cr0 |= 0x10; + if (!(cr0 & 0x80000000)) + mmu_perm = 4; + if (hascache && !(cr0 & (1 << 30))) + cpu_cache_int_enabled = 1; + else + cpu_cache_int_enabled = 0; + if (hascache && ((cr0 ^ old_cr0) & (1 << 30))) + cpu_update_waitstates(); + if (cr0 & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + break; + case 2: + cr2 = cpu_state.regs[cpu_rm].l; + break; + case 3: + cr3 = cpu_state.regs[cpu_rm].l; + flushmmucache(); + break; + case 4: + if (cpu_has_feature(CPU_FEATURE_CR4)) { + if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) + flushmmucache(); + cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; break; - case 4: - if (cpu_has_feature(CPU_FEATURE_CR4)) - { - if (((cpu_state.regs[cpu_rm].l ^ cr4) & cpu_CR4_mask) & CR4_PAE) - flushmmucache(); - cr4 = cpu_state.regs[cpu_rm].l & cpu_CR4_mask; + } + + default: + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + break; + } + CLOCK_CYCLES(10); + PREFETCH_RUN(10, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static int +opMOV_DRx_r_a16(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_DRx_r_a32(uint32_t fetchdat) +{ + if ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + dr[cpu_reg] = cpu_state.regs[cpu_rm].l; + CLOCK_CYCLES(6); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_r_TRx(void) +{ + uint32_t base; + + base = _tr[4] & 0xfffff800; + switch (cpu_reg) { + case 3: + pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); + _tr[3] = *(uint32_t *) &(_cache[cache_index]); + cache_index = (cache_index + 4) & 0xf; + break; + } + cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; + CLOCK_CYCLES(6); +} +static int +opMOV_r_TRx_a16(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; +} +static int +opMOV_r_TRx_a32(uint32_t fetchdat) +{ + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_r_TRx(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; +} + +static void +opMOV_TRx_r(void) +{ + uint32_t base; + int i, ctl; + + _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; + base = _tr[4] & 0xfffff800; + ctl = _tr[5] & 3; + switch (cpu_reg) { + case 3: + pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); + *(uint32_t *) &(_cache[cache_index]) = _tr[3]; + cache_index = (cache_index + 4) & 0xf; + break; + case 4: + if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) + pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); + break; + case 5: + pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); + if (!(_tr[5] & (1 << 19))) { + switch (ctl) { + case 0: + pclog(" Cache fill or read...\n", base); + break; + case 1: + base += (_tr[5] & 0x7f0); + pclog(" Writing 16 bytes to %08X...\n", base); + for (i = 0; i < 16; i += 4) + mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); + break; + case 2: + base += (_tr[5] & 0x7f0); + pclog(" Reading 16 bytes from %08X...\n", base); + for (i = 0; i < 16; i += 4) + *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); + break; + case 3: + pclog(" Cache invalidate/flush...\n", base); break; } - - default: - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - break; - } - CLOCK_CYCLES(10); - PREFETCH_RUN(10, 2, rmdat, 0,0,0,0, 1); - return 0; + } + break; + } + CLOCK_CYCLES(6); } - -static int opMOV_DRx_r_a16(uint32_t fetchdat) +static int +opMOV_TRx_r_a16(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_16(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int opMOV_DRx_r_a32(uint32_t fetchdat) +static int +opMOV_TRx_r_a32(uint32_t fetchdat) { - if ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1)) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - dr[cpu_reg] = cpu_state.regs[cpu_rm].l; - CLOCK_CYCLES(6); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static void opMOV_r_TRx(void) -{ - uint32_t base; - - base = _tr[4] & 0xfffff800; - switch (cpu_reg) { - case 3: - pclog("[R] %08X cache = %08X\n", base + cache_index, _tr[3]); - _tr[3] = *(uint32_t *) &(_cache[cache_index]); - cache_index = (cache_index + 4) & 0xf; - break; - } - cpu_state.regs[cpu_rm].l = _tr[cpu_reg]; - CLOCK_CYCLES(6); -} -static int opMOV_r_TRx_a16(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - opMOV_r_TRx(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_r_TRx_a32(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - opMOV_r_TRx(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; -} - -static void opMOV_TRx_r(void) -{ - uint32_t base; - int i, ctl; - - _tr[cpu_reg] = cpu_state.regs[cpu_rm].l; - base = _tr[4] & 0xfffff800; - ctl = _tr[5] & 3; - switch (cpu_reg) { - case 3: - pclog("[W] %08X cache = %08X\n", base + cache_index, _tr[3]); - *(uint32_t *) &(_cache[cache_index]) = _tr[3]; - cache_index = (cache_index + 4) & 0xf; - break; - case 4: - if (!(cr0 & 1) && !(_tr[5] & (1 << 19))) - pclog("TAG = %08X, DEST = %08X\n", base, base + cache_index - 16); - break; - case 5: - pclog("[16] EXT = %i (%i), SET = %04X\n", !!(_tr[5] & (1 << 19)), _tr[5] & 0x03, _tr[5] & 0x7f0); - if (!(_tr[5] & (1 << 19))) { - switch(ctl) { - case 0: - pclog(" Cache fill or read...\n", base); - break; - case 1: - base += (_tr[5] & 0x7f0); - pclog(" Writing 16 bytes to %08X...\n", base); - for (i = 0; i < 16; i += 4) - mem_writel_phys(base + i, *(uint32_t *) &(_cache[i])); - break; - case 2: - base += (_tr[5] & 0x7f0); - pclog(" Reading 16 bytes from %08X...\n", base); - for (i = 0; i < 16; i += 4) - *(uint32_t *) &(_cache[i]) = mem_readl_phys(base + i); - break; - case 3: - pclog(" Cache invalidate/flush...\n", base); - break; - } - } - break; - } - CLOCK_CYCLES(6); -} -static int opMOV_TRx_r_a16(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_16(fetchdat); - opMOV_TRx_r(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 0); - return 0; -} -static int opMOV_TRx_r_a32(uint32_t fetchdat) -{ - if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags&VM_FLAG)) && (cr0&1))) - { - x86gpf(NULL, 0); - return 1; - } - fetch_ea_32(fetchdat); - opMOV_TRx_r(); - PREFETCH_RUN(6, 2, rmdat, 0,0,0,0, 1); - return 0; + if ((cpu_s->cpu_type == CPU_PENTIUM) || ((CPL || (cpu_state.eflags & VM_FLAG)) && (cr0 & 1))) { + x86gpf(NULL, 0); + return 1; + } + fetch_ea_32(fetchdat); + opMOV_TRx_r(); + PREFETCH_RUN(6, 2, rmdat, 0, 0, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index 02e2d50de..be8acb618 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -1,445 +1,532 @@ -static int opMOV_w_seg_a16(uint32_t fetchdat) +static int +opMOV_w_seg_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + seteaw(ES); + break; + case 0x08: /*CS*/ + seteaw(CS); + break; + case 0x18: /*DS*/ + seteaw(DS); + break; + case 0x10: /*SS*/ + seteaw(SS); + break; + case 0x20: /*FS*/ + seteaw(FS); + break; + case 0x28: /*GS*/ + seteaw(GS); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; +} +static int +opMOV_w_seg_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + seteaw(ES); + break; + case 0x08: /*CS*/ + seteaw(CS); + break; + case 0x18: /*DS*/ + seteaw(DS); + break; + case 0x10: /*SS*/ + seteaw(SS); + break; + case 0x20: /*FS*/ + seteaw(FS); + break; + case 0x28: /*GS*/ + seteaw(GS); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; +} + +static int +opMOV_l_seg_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = ES; + else seteaw(ES); - break; - case 0x08: /*CS*/ + break; + case 0x08: /*CS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = CS; + else seteaw(CS); - break; - case 0x18: /*DS*/ + break; + case 0x18: /*DS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = DS; + else seteaw(DS); - break; - case 0x10: /*SS*/ + break; + case 0x10: /*SS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = SS; + else seteaw(SS); - break; - case 0x20: /*FS*/ + break; + case 0x20: /*FS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = FS; + else seteaw(FS); - break; - case 0x28: /*GS*/ + break; + case 0x28: /*GS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = GS; + else seteaw(GS); - break; - } + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; } -static int opMOV_w_seg_a32(uint32_t fetchdat) +static int +opMOV_l_seg_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = ES; + else seteaw(ES); - break; - case 0x08: /*CS*/ + break; + case 0x08: /*CS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = CS; + else seteaw(CS); - break; - case 0x18: /*DS*/ + break; + case 0x18: /*DS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = DS; + else seteaw(DS); - break; - case 0x10: /*SS*/ + break; + case 0x10: /*SS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = SS; + else seteaw(SS); - break; - case 0x20: /*FS*/ + break; + case 0x20: /*FS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = FS; + else seteaw(FS); - break; - case 0x28: /*GS*/ + break; + case 0x28: /*GS*/ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].l = GS; + else seteaw(GS); - break; - } + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; } -static int opMOV_l_seg_a16(uint32_t fetchdat) +static int +opMOV_seg_w_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); + uint16_t new_seg; - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + new_seg = geteaw(); + if (cpu_state.abrt) + return 1; - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_l_seg_a32(uint32_t fetchdat) -{ - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = ES; - else seteaw(ES); - break; - case 0x08: /*CS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = CS; - else seteaw(CS); - break; - case 0x18: /*DS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = DS; - else seteaw(DS); - break; - case 0x10: /*SS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = SS; - else seteaw(SS); - break; - case 0x20: /*FS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = FS; - else seteaw(FS); - break; - case 0x28: /*GS*/ - if (cpu_mod == 3) cpu_state.regs[cpu_rm].l = GS; - else seteaw(GS); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 3); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 3, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; -} - -static int opMOV_seg_w_a16(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } - - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 0); - return cpu_state.abrt; -} -static int opMOV_seg_w_a32(uint32_t fetchdat) -{ - uint16_t new_seg; - - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - new_seg=geteaw(); if (cpu_state.abrt) return 1; - - switch (rmdat & 0x38) - { - case 0x00: /*ES*/ - loadseg(new_seg, &cpu_state.seg_es); - break; - case 0x18: /*DS*/ - loadseg(new_seg, &cpu_state.seg_ds); - break; - case 0x10: /*SS*/ - loadseg(new_seg, &cpu_state.seg_ss); - if (cpu_state.abrt) return 1; - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) return 1; - case 0x20: /*FS*/ - loadseg(new_seg, &cpu_state.seg_fs); - break; - case 0x28: /*GS*/ - loadseg(new_seg, &cpu_state.seg_gs); - break; - } + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return 1; + case 0x20: /*FS*/ + loadseg(new_seg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.seg_gs); + break; + } - CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,0, 1); - return cpu_state.abrt; + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 0); + return cpu_state.abrt; } - - -static int opLDS_w_a16(uint32_t fetchdat) +static int +opMOV_seg_w_a32(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t new_seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); - return 0; -} -static int opLDS_w_a32(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); - return 0; -} -static int opLDS_l_a16(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); - return 0; -} -static int opLDS_l_a32(uint32_t fetchdat) -{ - uint32_t addr; - uint16_t seg; - - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state. eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ds); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); - return 0; -} - -static int opLSS_w_a16(uint32_t fetchdat) -{ - uint16_t addr, seg; - - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); + new_seg = geteaw(); + if (cpu_state.abrt) return 1; + + switch (rmdat & 0x38) { + case 0x00: /*ES*/ + loadseg(new_seg, &cpu_state.seg_es); + break; + case 0x18: /*DS*/ + loadseg(new_seg, &cpu_state.seg_ds); + break; + case 0x10: /*SS*/ + loadseg(new_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return 1; + case 0x20: /*FS*/ + loadseg(new_seg, &cpu_state.seg_fs); + break; + case 0x28: /*GS*/ + loadseg(new_seg, &cpu_state.seg_gs); + break; + } + + CLOCK_CYCLES((cpu_mod == 3) ? 2 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 2 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, 0, 1); + return cpu_state.abrt; } -static int opLSS_w_a32(uint32_t fetchdat) + +static int +opLDS_w_a16(uint32_t fetchdat) { - uint16_t addr, seg; + uint16_t addr, seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - addr = readmemw(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 0; } -static int opLSS_l_a16(uint32_t fetchdat) +static int +opLDS_w_a32(uint32_t fetchdat) { - uint32_t addr; - uint16_t seg; + uint16_t addr, seg; - fetch_ea_16(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 0; } -static int opLSS_l_a32(uint32_t fetchdat) +static int +opLDS_l_a16(uint32_t fetchdat) { - uint32_t addr; - uint16_t seg; + uint32_t addr; + uint16_t seg; - fetch_ea_32(fetchdat); - ILLEGAL_ON(cpu_mod == 3); - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); - addr = readmeml(easeg, cpu_state.eaaddr); - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; - loadseg(seg, &cpu_state.seg_ss); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = addr; - - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); + return 0; +} +static int +opLDS_l_a32(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ds); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); + return 0; } -#define opLsel(name, sel) \ - static int opL ## name ## _w_a16(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_16(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _w_a32(uint32_t fetchdat) \ - { \ - uint16_t addr, seg; \ - \ - fetch_ea_32(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ - addr = readmemw(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].w = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 2,0,0,0, 1); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a16(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_16(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 0); \ - return 0; \ - } \ - \ - static int opL ## name ## _l_a32(uint32_t fetchdat) \ - { \ - uint32_t addr; \ - uint16_t seg; \ - \ - fetch_ea_32(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - ILLEGAL_ON(cpu_mod == 3); \ - CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ - addr = readmeml(easeg, cpu_state.eaaddr); \ - seg = readmemw(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 1; \ - loadseg(seg, &sel); if (cpu_state.abrt) return 1; \ - cpu_state.regs[cpu_reg].l = addr; \ - \ - CLOCK_CYCLES(7); \ - PREFETCH_RUN(7, 2, rmdat, 1,1,0,0, 1); \ - return 0; \ - } +static int +opLSS_w_a16(uint32_t fetchdat) +{ + uint16_t addr, seg; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 1; +} +static int +opLSS_w_a32(uint32_t fetchdat) +{ + uint16_t addr, seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + addr = readmemw(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 1; +} +static int +opLSS_l_a16(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_16(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); + return 1; +} +static int +opLSS_l_a32(uint32_t fetchdat) +{ + uint32_t addr; + uint16_t seg; + + fetch_ea_32(fetchdat); + ILLEGAL_ON(cpu_mod == 3); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); + addr = readmeml(easeg, cpu_state.eaaddr); + seg = readmemw(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 1; + loadseg(seg, &cpu_state.seg_ss); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = addr; + + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); + return 1; +} + +#define opLsel(name, sel) \ + static int opL##name##_w_a16(uint32_t fetchdat) \ + { \ + uint16_t addr, seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + addr = readmemw(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opL##name##_w_a32(uint32_t fetchdat) \ + { \ + uint16_t addr, seg; \ + \ + fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); \ + addr = readmemw(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 2); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].w = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 2, 0, 0, 0, 1); \ + return 0; \ + } \ + \ + static int opL##name##_l_a16(uint32_t fetchdat) \ + { \ + uint32_t addr; \ + uint16_t seg; \ + \ + fetch_ea_16(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ + addr = readmeml(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 0); \ + return 0; \ + } \ + \ + static int opL##name##_l_a32(uint32_t fetchdat) \ + { \ + uint32_t addr; \ + uint16_t seg; \ + \ + fetch_ea_32(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + ILLEGAL_ON(cpu_mod == 3); \ + CHECK_READ(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 5); \ + addr = readmeml(easeg, cpu_state.eaaddr); \ + seg = readmemw(easeg, cpu_state.eaaddr + 4); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(seg, &sel); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.regs[cpu_reg].l = addr; \ + \ + CLOCK_CYCLES(7); \ + PREFETCH_RUN(7, 2, rmdat, 1, 1, 0, 0, 1); \ + return 0; \ + } opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) diff --git a/src/cpu/x86_ops_movx.h b/src/cpu/x86_ops_movx.h index 3ad89b7f0..1b607fb8b 100644 --- a/src/cpu/x86_ops_movx.h +++ b/src/cpu/x86_ops_movx.h @@ -1,209 +1,251 @@ -static int opMOVZX_w_b_a16(uint32_t fetchdat) +static int +opMOVZX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_w_b_a32(uint32_t fetchdat) +static int +opMOVZX_w_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_l_b_a16(uint32_t fetchdat) +static int +opMOVZX_l_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_l_b_a32(uint32_t fetchdat) +static int +opMOVZX_l_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_w_w_a16(uint32_t fetchdat) +static int +opMOVZX_w_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_w_w_a32(uint32_t fetchdat) +static int +opMOVZX_w_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVZX_l_w_a16(uint32_t fetchdat) +static int +opMOVZX_l_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVZX_l_w_a32(uint32_t fetchdat) +static int +opMOVZX_l_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_w_b_a16(uint32_t fetchdat) +static int +opMOVSX_w_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].w |= 0xff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_w_b_a32(uint32_t fetchdat) +static int +opMOVSX_w_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = (uint16_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].w |= 0xff00; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = (uint16_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].w |= 0xff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_l_b_a16(uint32_t fetchdat) +static int +opMOVSX_l_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].l |= 0xffffff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_l_b_a32(uint32_t fetchdat) +static int +opMOVSX_l_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x80) - cpu_state.regs[cpu_reg].l |= 0xffffff00; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x80) + cpu_state.regs[cpu_reg].l |= 0xffffff00; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } -static int opMOVSX_l_w_a16(uint32_t fetchdat) +static int +opMOVSX_l_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x8000) + cpu_state.regs[cpu_reg].l |= 0xffff0000; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 0); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 0); + return 0; } -static int opMOVSX_l_w_a32(uint32_t fetchdat) +static int +opMOVSX_l_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = (uint32_t)temp; - if (temp & 0x8000) - cpu_state.regs[cpu_reg].l |= 0xffff0000; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = (uint32_t) temp; + if (temp & 0x8000) + cpu_state.regs[cpu_reg].l |= 0xffff0000; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0:1,0,0,0, 1); - return 0; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_msr.h b/src/cpu/x86_ops_msr.h index cdf9d8612..daae01d84 100644 --- a/src/cpu/x86_ops_msr.h +++ b/src/cpu/x86_ops_msr.h @@ -1,34 +1,33 @@ -static int opRDTSC(uint32_t fetchdat) +static int +opRDTSC(uint32_t fetchdat) { - if (!cpu_has_feature(CPU_FEATURE_RDTSC)) - { - cpu_state.pc = cpu_state.oldpc; - x86illegal(); - return 1; - } - if ((cr4 & CR4_TSD) && CPL) - { - x86gpf("RDTSC when TSD set and CPL != 0", 0); - return 1; - } - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - CLOCK_CYCLES(1); + if (!cpu_has_feature(CPU_FEATURE_RDTSC)) { + cpu_state.pc = cpu_state.oldpc; + x86illegal(); + return 1; + } + if ((cr4 & CR4_TSD) && CPL) { + x86gpf("RDTSC when TSD set and CPL != 0", 0); + return 1; + } + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + CLOCK_CYCLES(1); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); #endif - return 0; + return 0; } -static int opRDPMC(uint32_t fetchdat) +static int +opRDPMC(uint32_t fetchdat) { - if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) - { - x86gpf("RDPMC not allowed", 0); - return 1; - } - EAX = EDX = 0; - CLOCK_CYCLES(1); - return 0; + if (ECX > 1 || (!(cr4 & CR4_PCE) && (cr0 & 1) && CPL)) { + x86gpf("RDPMC not allowed", 0); + return 1; + } + EAX = EDX = 0; + CLOCK_CYCLES(1); + return 0; } diff --git a/src/cpu/x86_ops_mul.h b/src/cpu/x86_ops_mul.h index ca12a9add..552a9973a 100644 --- a/src/cpu/x86_ops_mul.h +++ b/src/cpu/x86_ops_mul.h @@ -1,263 +1,337 @@ -static int opIMUL_w_iw_a16(uint32_t fetchdat) +static int +opIMUL_w_iw_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getword(); + if (cpu_state.abrt) + return 1; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_iw_a32(uint32_t fetchdat) +static int +opIMUL_w_iw_a32(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getword(); if (cpu_state.abrt) return 1; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getword(); + if (cpu_state.abrt) + return 1; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 4, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_il_a16(uint32_t fetchdat) +static int +opIMUL_l_il_a16(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getlong(); + if (cpu_state.abrt) + return 1; - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(25); + PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_il_a32(uint32_t fetchdat) +static int +opIMUL_l_il_a32(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getlong(); if (cpu_state.abrt) return 1; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getlong(); + if (cpu_state.abrt) + return 1; - temp64 = ((int64_t)templ) * ((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(25); - PREFETCH_RUN(25, 6, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(25); + PREFETCH_RUN(25, 6, rmdat, 0, 1, 0, 0, 1); + return 0; } -static int opIMUL_w_ib_a16(uint32_t fetchdat) +static int +opIMUL_w_ib_a16(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (tempw2 & 0x80) + tempw2 |= 0xff00; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_ib_a32(uint32_t fetchdat) +static int +opIMUL_w_ib_a32(uint32_t fetchdat) { - int32_t templ; - int16_t tempw, tempw2; + int32_t templ; + int16_t tempw, tempw2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - tempw2 = getbyte(); if (cpu_state.abrt) return 1; - if (tempw2 & 0x80) tempw2 |= 0xff00; + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + tempw2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (tempw2 & 0x80) + tempw2 |= 0xff00; - templ = ((int)tempw) * ((int)tempw2); - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].w = templ & 0xffff; + templ = ((int) tempw) * ((int) tempw2); + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].w = templ & 0xffff; - CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); - PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES((cpu_mod == 3) ? 14 : 17); + PREFETCH_RUN((cpu_mod == 3) ? 14 : 17, 3, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_ib_a16(uint32_t fetchdat) +static int +opIMUL_l_ib_a16(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (templ2 & 0x80) + templ2 |= 0xffffff00; - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_ib_a32(uint32_t fetchdat) +static int +opIMUL_l_ib_a32(uint32_t fetchdat) { - int64_t temp64; - int32_t templ, templ2; + int64_t temp64; + int32_t templ, templ2; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - templ2 = getbyte(); if (cpu_state.abrt) return 1; - if (templ2 & 0x80) templ2 |= 0xffffff00; + templ = geteal(); + if (cpu_state.abrt) + return 1; + templ2 = getbyte(); + if (cpu_state.abrt) + return 1; + if (templ2 & 0x80) + templ2 |= 0xffffff00; - temp64 = ((int64_t)templ)*((int64_t)templ2); - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); - cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; + temp64 = ((int64_t) templ) * ((int64_t) templ2); + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + cpu_state.regs[cpu_reg].l = temp64 & 0xffffffff; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 3, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 3, rmdat, 0, 1, 0, 0, 1); + return 0; } - - -static int opIMUL_w_w_a16(uint32_t fetchdat) +static int +opIMUL_w_w_a16(uint32_t fetchdat) { - int32_t templ; + int32_t templ; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = templ & 0xFFFF; + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(18); + PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 0); + return 0; } -static int opIMUL_w_w_a32(uint32_t fetchdat) +static int +opIMUL_w_w_a32(uint32_t fetchdat) { - int32_t templ; + int32_t templ; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - templ = (int32_t)(int16_t)cpu_state.regs[cpu_reg].w * (int32_t)(int16_t)geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = templ & 0xFFFF; - flags_rebuild(); - if ((templ >> 15) != 0 && (templ >> 15) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + templ = (int32_t) (int16_t) cpu_state.regs[cpu_reg].w * (int32_t) (int16_t) geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = templ & 0xFFFF; + flags_rebuild(); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(18); - PREFETCH_RUN(18, 2, rmdat, 1,0,0,0, 1); - return 0; + CLOCK_CYCLES(18); + PREFETCH_RUN(18, 2, rmdat, 1, 0, 0, 0, 1); + return 0; } -static int opIMUL_l_l_a16(uint32_t fetchdat) +static int +opIMUL_l_l_a16(uint32_t fetchdat) { - int64_t temp64; + int64_t temp64; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 0); + return 0; } -static int opIMUL_l_l_a32(uint32_t fetchdat) +static int +opIMUL_l_l_a32(uint32_t fetchdat) { - int64_t temp64; + int64_t temp64; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = (int64_t)(int32_t)cpu_state.regs[cpu_reg].l * (int64_t)(int32_t)geteal(); - if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; - flags_rebuild(); - if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) cpu_state.flags |= C_FLAG | V_FLAG; - else cpu_state.flags &= ~(C_FLAG | V_FLAG); + temp64 = (int64_t) (int32_t) cpu_state.regs[cpu_reg].l * (int64_t) (int32_t) geteal(); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp64 & 0xFFFFFFFF; + flags_rebuild(); + if ((temp64 >> 31) != 0 && (temp64 >> 31) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); - CLOCK_CYCLES(30); - PREFETCH_RUN(30, 2, rmdat, 0,1,0,0, 1); - return 0; + CLOCK_CYCLES(30); + PREFETCH_RUN(30, 2, rmdat, 0, 1, 0, 0, 1); + return 0; } diff --git a/src/cpu/x86_ops_pmode.h b/src/cpu/x86_ops_pmode.h index 698cfc838..4fee881ea 100644 --- a/src/cpu/x86_ops_pmode.h +++ b/src/cpu/x86_ops_pmode.h @@ -1,460 +1,513 @@ -static int opARPL_a16(uint32_t fetchdat) +static int +opARPL_a16(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp_seg = geteaw(); if (cpu_state.abrt) return 1; + NOTRM + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); + if (cpu_state.abrt) + return 1; - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - cpu_state.flags |= Z_FLAG; - } - else - cpu_state.flags &= ~Z_FLAG; + flags_rebuild(); + if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) { + temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); + seteaw(temp_seg); + if (cpu_state.abrt) + return 1; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 0); - return 0; + CLOCK_CYCLES(is486 ? 9 : 20); + PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 0); + return 0; } -static int opARPL_a32(uint32_t fetchdat) +static int +opARPL_a32(uint32_t fetchdat) { - uint16_t temp_seg; + uint16_t temp_seg; - NOTRM - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp_seg = geteaw(); if (cpu_state.abrt) return 1; + NOTRM + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp_seg = geteaw(); + if (cpu_state.abrt) + return 1; - flags_rebuild(); - if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) - { - temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); - seteaw(temp_seg); if (cpu_state.abrt) return 1; - cpu_state.flags |= Z_FLAG; - } - else - cpu_state.flags &= ~Z_FLAG; + flags_rebuild(); + if ((temp_seg & 3) < (cpu_state.regs[cpu_reg].w & 3)) { + temp_seg = (temp_seg & 0xfffc) | (cpu_state.regs[cpu_reg].w & 3); + seteaw(temp_seg); + if (cpu_state.abrt) + return 1; + cpu_state.flags |= Z_FLAG; + } else + cpu_state.flags &= ~Z_FLAG; - CLOCK_CYCLES(is486 ? 9 : 20); - PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1,0,1,0, 1); - return 0; + CLOCK_CYCLES(is486 ? 9 : 20); + PREFETCH_RUN(is486 ? 9 : 20, 2, rmdat, 1, 0, 1, 0, 1); + return 0; } -#define opLAR(name, fetch_ea, is32, ea32) \ - static int opLAR_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - \ - flags_rebuild(); \ - if (!(sel & 0xfffc)) { cpu_state.flags &= ~Z_FLAG; return 0; } /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - cpu_state.flags &= ~Z_FLAG; \ - if ((desc & 0x1f00) == 0x000) valid = 0; \ - if ((desc & 0x1f00) == 0x800) valid = 0; \ - if ((desc & 0x1f00) == 0xa00) valid = 0; \ - if ((desc & 0x1f00) == 0xd00) valid = 0; \ - if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int dpl = (desc >> 13) & 3; \ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - cpu_state.flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(11); \ - PREFETCH_RUN(11, 2, rmdat, 2,0,0,0, ea32); \ - return cpu_state.abrt; \ - } +#define opLAR(name, fetch_ea, is32, ea32) \ + static int opLAR_##name(uint32_t fetchdat) \ + { \ + int valid; \ + uint16_t sel, desc = 0; \ + \ + NOTRM \ + fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + \ + flags_rebuild(); \ + if (!(sel & 0xfffc)) { \ + cpu_state.flags &= ~Z_FLAG; \ + return 0; \ + } /*Null selector*/ \ + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ + if (valid) { \ + cpl_override = 1; \ + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ + cpl_override = 0; \ + if (cpu_state.abrt) \ + return 1; \ + } \ + cpu_state.flags &= ~Z_FLAG; \ + if ((desc & 0x1f00) == 0x000) \ + valid = 0; \ + if ((desc & 0x1f00) == 0x800) \ + valid = 0; \ + if ((desc & 0x1f00) == 0xa00) \ + valid = 0; \ + if ((desc & 0x1f00) == 0xd00) \ + valid = 0; \ + if ((desc & 0x1c00) < 0x1c00) /*Exclude conforming code segments*/ \ + { \ + int dpl = (desc >> 13) & 3; \ + if (dpl < CPL || dpl < (sel & 3)) \ + valid = 0; \ + } \ + if (valid) { \ + cpu_state.flags |= Z_FLAG; \ + cpl_override = 1; \ + if (is32) \ + cpu_state.regs[cpu_reg].l = readmeml(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xffff00; \ + else \ + cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4) & 0xff00; \ + cpl_override = 0; \ + } \ + CLOCK_CYCLES(11); \ + PREFETCH_RUN(11, 2, rmdat, 2, 0, 0, 0, ea32); \ + return cpu_state.abrt; \ + } opLAR(w_a16, fetch_ea_16, 0, 0) -opLAR(w_a32, fetch_ea_32, 0, 1) -opLAR(l_a16, fetch_ea_16, 1, 0) -opLAR(l_a32, fetch_ea_32, 1, 1) + opLAR(w_a32, fetch_ea_32, 0, 1) + opLAR(l_a16, fetch_ea_16, 1, 0) + opLAR(l_a32, fetch_ea_32, 1, 1) -#define opLSL(name, fetch_ea, is32, ea32) \ - static int opLSL_ ## name(uint32_t fetchdat) \ - { \ - int valid; \ - uint16_t sel, desc = 0; \ - \ - NOTRM \ - fetch_ea(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - \ - sel = geteaw(); if (cpu_state.abrt) return 1; \ - flags_rebuild(); \ - cpu_state.flags &= ~Z_FLAG; \ - if (!(sel & 0xfffc)) return 0; /*Null selector*/ \ - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ - if (valid) \ - { \ - cpl_override = 1; \ - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ - cpl_override = 0; if (cpu_state.abrt) return 1; \ - } \ - if ((desc & 0x1400) == 0x400) valid = 0; /*Interrupt or trap or call gate*/ \ - if ((desc & 0x1f00) == 0x000) valid = 0; /*Invalid*/ \ - if ((desc & 0x1f00) == 0xa00) valid = 0; /*Invalid*/ \ - if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ - { \ - int rpl = (desc >> 13) & 3; \ - if (rpl < CPL || rpl < (sel & 3)) valid = 0; \ - } \ - if (valid) \ - { \ - cpu_state.flags |= Z_FLAG; \ - cpl_override = 1; \ - if (is32) \ - { \ - cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ - if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) \ - { \ - cpu_state.regs[cpu_reg].l <<= 12; \ - cpu_state.regs[cpu_reg].l |= 0xFFF; \ - } \ - } \ - else \ - cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ - cpl_override = 0; \ - } \ - CLOCK_CYCLES(10); \ - PREFETCH_RUN(10, 2, rmdat, 4,0,0,0, ea32); \ - return cpu_state.abrt; \ - } +#define opLSL(name, fetch_ea, is32, ea32) \ + static int opLSL_##name(uint32_t fetchdat) \ + { \ + int valid; \ + uint16_t sel, desc = 0; \ + \ + NOTRM \ + fetch_ea(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + \ + sel = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + flags_rebuild(); \ + cpu_state.flags &= ~Z_FLAG; \ + if (!(sel & 0xfffc)) \ + return 0; /*Null selector*/ \ + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); \ + if (valid) { \ + cpl_override = 1; \ + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); \ + cpl_override = 0; \ + if (cpu_state.abrt) \ + return 1; \ + } \ + if ((desc & 0x1400) == 0x400) \ + valid = 0; /*Interrupt or trap or call gate*/ \ + if ((desc & 0x1f00) == 0x000) \ + valid = 0; /*Invalid*/ \ + if ((desc & 0x1f00) == 0xa00) \ + valid = 0; /*Invalid*/ \ + if ((desc & 0x1c00) != 0x1c00) /*Exclude conforming code segments*/ \ + { \ + int rpl = (desc >> 13) & 3; \ + if (rpl < CPL || rpl < (sel & 3)) \ + valid = 0; \ + } \ + if (valid) { \ + cpu_state.flags |= Z_FLAG; \ + cpl_override = 1; \ + if (is32) { \ + cpu_state.regs[cpu_reg].l = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ + cpu_state.regs[cpu_reg].l |= (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0xF) << 16; \ + if (readmemb(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 6) & 0x80) { \ + cpu_state.regs[cpu_reg].l <<= 12; \ + cpu_state.regs[cpu_reg].l |= 0xFFF; \ + } \ + } else \ + cpu_state.regs[cpu_reg].w = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7)); \ + cpl_override = 0; \ + } \ + CLOCK_CYCLES(10); \ + PREFETCH_RUN(10, 2, rmdat, 4, 0, 0, 0, ea32); \ + return cpu_state.abrt; \ + } -opLSL(w_a16, fetch_ea_16, 0, 0) -opLSL(w_a32, fetch_ea_32, 0, 1) -opLSL(l_a16, fetch_ea_16, 1, 0) -opLSL(l_a32, fetch_ea_32, 1, 1) + opLSL(w_a16, fetch_ea_16, 0, 0) + opLSL(w_a32, fetch_ea_32, 0, 1) + opLSL(l_a16, fetch_ea_16, 1, 0) + opLSL(l_a32, fetch_ea_32, 1, 1) - -static int op0F00_common(uint32_t fetchdat, int ea32) + static int op0F00_common(uint32_t fetchdat, int ea32) { - int dpl, valid, granularity; - uint32_t addr, base, limit; - uint16_t desc, sel; - uint8_t access, ar_high; + int dpl, valid, granularity; + uint32_t addr, base, limit; + uint16_t desc, sel; + uint8_t access, ar_high; - switch (rmdat & 0x38) - { - case 0x00: /*SLDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(ldt.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); + switch (rmdat & 0x38) { + case 0x00: /*SLDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(ldt.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x08: /*STR*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(tr.seg); + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x10: /*LLDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); + return 1; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + addr = (sel & ~7) + gdt.base; + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); + access = readmemb(0, addr + 5); + ar_high = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + ldt.limit = limit; + ldt.access = access; + ldt.ar_high = ar_high; + if (granularity) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base = base; + ldt.seg = sel; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32); + break; + case 0x18: /*LTR*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x08: /*STR*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(tr.seg); - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x10: /*LLDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - return 1; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - ar_high = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - ldt.limit = limit; - ldt.access = access; - ldt.ar_high = ar_high; - if (granularity) - { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = base; - ldt.seg = sel; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x18: /*LTR*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - addr = (sel & ~7) + gdt.base; - limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); - base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); - access = readmemb(0, addr + 5); - ar_high = readmemb(0, addr + 6); - granularity = readmemb(0, addr + 6) & 0x80; - if (cpu_state.abrt) return 1; - access |= 2; - writememb(0, addr + 5, access); - if (cpu_state.abrt) return 1; - tr.seg = sel; - tr.limit = limit; - tr.access = access; - tr.ar_high = ar_high; - if (granularity) - { - tr.limit <<= 12; - tr.limit |= 0xFFF; - } - tr.base = base; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0:1,2,0,0, ea32); - break; - case 0x20: /*VERR*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - cpu_state.flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; - if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ - { - dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - } - if ((desc & 0x0800) && !(desc & 0x0200)) valid = 0; /*Non-readable code*/ - if (valid) cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; - case 0x28: /*VERW*/ - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - sel = geteaw(); if (cpu_state.abrt) return 1; - flags_rebuild(); - cpu_state.flags &= ~Z_FLAG; - if (!(sel & 0xfffc)) return 0; /*Null selector*/ - cpl_override = 1; - valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); - desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); - cpl_override = 0; if (cpu_state.abrt) return 1; - if (!(desc & 0x1000)) valid = 0; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + addr = (sel & ~7) + gdt.base; + limit = readmemw(0, addr) + ((readmemb(0, addr + 6) & 0xf) << 16); + base = (readmemw(0, addr + 2)) | (readmemb(0, addr + 4) << 16) | (readmemb(0, addr + 7) << 24); + access = readmemb(0, addr + 5); + ar_high = readmemb(0, addr + 6); + granularity = readmemb(0, addr + 6) & 0x80; + if (cpu_state.abrt) + return 1; + access |= 2; + writememb(0, addr + 5, access); + if (cpu_state.abrt) + return 1; + tr.seg = sel; + tr.limit = limit; + tr.access = access; + tr.ar_high = ar_high; + if (granularity) { + tr.limit <<= 12; + tr.limit |= 0xFFF; + } + tr.base = base; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 2, 0, 0, ea32); + break; + case 0x20: /*VERR*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.flags &= ~Z_FLAG; + if (!(sel & 0xfffc)) + return 0; /*Null selector*/ + cpl_override = 1; + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); + cpl_override = 0; + if (cpu_state.abrt) + return 1; + if (!(desc & 0x1000)) + valid = 0; + if ((desc & 0xC00) != 0xC00) /*Exclude conforming code segments*/ + { dpl = (desc >> 13) & 3; /*Check permissions*/ - if (dpl < CPL || dpl < (sel & 3)) valid = 0; - if (desc & 0x0800) valid = 0; /*Code*/ - if (!(desc & 0x0200)) valid = 0; /*Read-only data*/ - if (valid) cpu_state.flags |= Z_FLAG; - CLOCK_CYCLES(20); - PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1:2,0,0,0, ea32); - break; + if (dpl < CPL || dpl < (sel & 3)) + valid = 0; + } + if ((desc & 0x0800) && !(desc & 0x0200)) + valid = 0; /*Non-readable code*/ + if (valid) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; + case 0x28: /*VERW*/ + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + sel = geteaw(); + if (cpu_state.abrt) + return 1; + flags_rebuild(); + cpu_state.flags &= ~Z_FLAG; + if (!(sel & 0xfffc)) + return 0; /*Null selector*/ + cpl_override = 1; + valid = (sel & ~7) < ((sel & 4) ? ldt.limit : gdt.limit); + desc = readmemw(0, ((sel & 4) ? ldt.base : gdt.base) + (sel & ~7) + 4); + cpl_override = 0; + if (cpu_state.abrt) + return 1; + if (!(desc & 0x1000)) + valid = 0; + dpl = (desc >> 13) & 3; /*Check permissions*/ + if (dpl < CPL || dpl < (sel & 3)) + valid = 0; + if (desc & 0x0800) + valid = 0; /*Code*/ + if (!(desc & 0x0200)) + valid = 0; /*Read-only data*/ + if (valid) + cpu_state.flags |= Z_FLAG; + CLOCK_CYCLES(20); + PREFETCH_RUN(20, 2, rmdat, (cpu_mod == 3) ? 1 : 2, 0, 0, 0, ea32); + break; - default: - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + default: + cpu_state.pc -= 3; + x86illegal(); + break; + } + return cpu_state.abrt; } -static int op0F00_a16(uint32_t fetchdat) +static int +op0F00_a16(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F00_common(fetchdat, 0); + return op0F00_common(fetchdat, 0); } -static int op0F00_a32(uint32_t fetchdat) +static int +op0F00_a32(uint32_t fetchdat) { - NOTRM + NOTRM - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F00_common(fetchdat, 1); + return op0F00_common(fetchdat, 1); } -static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) +static int +op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { - uint32_t base; - uint16_t limit, tempw; - switch (rmdat & 0x38) - { - case 0x00: /*SGDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(gdt.limit); - base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); + uint32_t base; + uint16_t limit, tempw; + switch (rmdat & 0x38) { + case 0x00: /*SGDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(gdt.limit); + base = gdt.base; // is32 ? gdt.base : (gdt.base & 0xffffff); + if (is286) + base |= 0xff000000; + writememl(easeg, cpu_state.eaaddr + 2, base); + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); + break; + case 0x08: /*SIDT*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(idt.limit); + base = idt.base; + if (is286) + base |= 0xff000000; + writememl(easeg, cpu_state.eaaddr + 2, base); + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 2, rmdat, 0, 0, 1, 1, ea32); + break; + case 0x10: /*LGDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x08: /*SIDT*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(idt.limit); - base = idt.base; - if (is286) - base |= 0xff000000; - writememl(easeg, cpu_state.eaaddr + 2, base); - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 2, rmdat, 0,0,1,1, ea32); + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + limit = geteaw(); + base = readmeml(0, easeg + cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + gdt.limit = limit; + gdt.base = base; + if (!is32) + gdt.base &= 0xffffff; + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32); + break; + case 0x18: /*LIDT*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); break; - case 0x10: /*LGDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + limit = geteaw(); + base = readmeml(0, easeg + cpu_state.eaaddr + 2); + if (cpu_state.abrt) + return 1; + idt.limit = limit; + idt.base = base; + if (!is32) + idt.base &= 0xffffff; + CLOCK_CYCLES(11); + PREFETCH_RUN(11, 2, rmdat, 1, 1, 0, 0, ea32); + break; + + case 0x20: /*SMSW*/ + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (is486 || isibm486) + seteaw(msw); + else if (is386) + seteaw(msw | /* 0xFF00 */ 0xFFE0); + else + seteaw(msw | 0xFFF0); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + case 0x30: /*LMSW*/ + if ((CPL || cpu_state.eflags & VM_FLAG) && (msw & 1)) { + x86gpf(NULL, 0); + break; + } + if (cpu_mod != 3) + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + if (msw & 1) + tempw |= 1; + if (is386) { + tempw &= ~0x10; + tempw |= (msw & 0x10); + } else + tempw &= 0xF; + msw = tempw; + if (msw & 1) + cpu_cur_status |= CPU_STATUS_PMODE; + else + cpu_cur_status &= ~CPU_STATUS_PMODE; + PREFETCH_RUN(2, 2, rmdat, 0, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); + break; + + case 0x38: /*INVLPG*/ + if (is486 || isibm486) { + if ((CPL || cpu_state.eflags & VM_FLAG) && (cr0 & 1)) { + x86gpf(NULL, 0); + break; } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - gdt.limit = limit; - gdt.base = base; - if (!is32) gdt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); - break; - case 0x18: /*LIDT*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL,0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - limit = geteaw(); - base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; - idt.limit = limit; - idt.base = base; - if (!is32) idt.base &= 0xffffff; - CLOCK_CYCLES(11); - PREFETCH_RUN(11, 2, rmdat, 1,1,0,0, ea32); + SEG_CHECK_READ(cpu_state.ea_seg); + mmu_invalidate(ds + cpu_state.eaaddr); + CLOCK_CYCLES(12); + PREFETCH_RUN(12, 2, rmdat, 0, 0, 0, 0, ea32); break; + } - case 0x20: /*SMSW*/ - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (is486 || isibm486) seteaw(msw); - else if (is386) seteaw(msw | /* 0xFF00 */ 0xFFE0); - else seteaw(msw | 0xFFF0); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - case 0x30: /*LMSW*/ - if ((CPL || cpu_state.eflags&VM_FLAG) && (msw&1)) - { - x86gpf(NULL, 0); - break; - } - if (cpu_mod != 3) - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); if (cpu_state.abrt) return 1; - if (msw & 1) tempw |= 1; - if (is386) - { - tempw &= ~0x10; - tempw |= (msw & 0x10); - } - else tempw &= 0xF; - msw = tempw; - if (msw & 1) - cpu_cur_status |= CPU_STATUS_PMODE; - else - cpu_cur_status &= ~CPU_STATUS_PMODE; - PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); - break; - - case 0x38: /*INVLPG*/ - if (is486 || isibm486) - { - if ((CPL || cpu_state.eflags&VM_FLAG) && (cr0&1)) - { - x86gpf(NULL, 0); - break; - } - SEG_CHECK_READ(cpu_state.ea_seg); - mmu_invalidate(ds + cpu_state.eaaddr); - CLOCK_CYCLES(12); - PREFETCH_RUN(12, 2, rmdat, 0,0,0,0, ea32); - break; - } - - default: - cpu_state.pc -= 3; - x86illegal(); - break; - } - return cpu_state.abrt; + default: + cpu_state.pc -= 3; + x86illegal(); + break; + } + return cpu_state.abrt; } -static int op0F01_w_a16(uint32_t fetchdat) +static int +op0F01_w_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 0, 0); + return op0F01_common(fetchdat, 0, 0, 0); } -static int op0F01_w_a32(uint32_t fetchdat) +static int +op0F01_w_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 0, 0, 1); + return op0F01_common(fetchdat, 0, 0, 1); } -static int op0F01_l_a16(uint32_t fetchdat) +static int +op0F01_l_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 1, 0, 0); + return op0F01_common(fetchdat, 1, 0, 0); } -static int op0F01_l_a32(uint32_t fetchdat) +static int +op0F01_l_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); + fetch_ea_32(fetchdat); - return op0F01_common(fetchdat, 1, 0, 1); + return op0F01_common(fetchdat, 1, 0, 1); } -static int op0F01_286(uint32_t fetchdat) +static int +op0F01_286(uint32_t fetchdat) { - fetch_ea_16(fetchdat); + fetch_ea_16(fetchdat); - return op0F01_common(fetchdat, 0, 1, 0); + return op0F01_common(fetchdat, 0, 1, 0); } diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index 3029da30a..4d4adb77d 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -1,67 +1,71 @@ -#define op_seg(name, seg, opcode_table, normal_opcode_table) \ -static int op ## name ## _w_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[fetchdat & 0xff]) \ - return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ - return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a16(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x100]) \ - return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ +#define op_seg(name, seg, opcode_table, normal_opcode_table) \ + static int op##name##_w_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[fetchdat & 0xff]) \ + return opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + return normal_opcode_table[fetchdat & 0xff](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a16(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x100]) \ + return opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x100](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _w_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x200]) \ - return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ + } \ + \ + static int op##name##_w_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x200]) \ + return opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x200](fetchdat >> 8); \ -} \ - \ -static int op ## name ## _l_a32(uint32_t fetchdat) \ -{ \ - fetchdat = fastreadl(cs + cpu_state.pc); \ - if (cpu_state.abrt) return 1; \ - cpu_state.pc++; \ - \ - cpu_state.ea_seg = &seg; \ - cpu_state.ssegs = 1; \ - CLOCK_CYCLES(4); \ - PREFETCH_PREFIX(); \ - \ - if (opcode_table[(fetchdat & 0xff) | 0x300]) \ - return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ + } \ + \ + static int op##name##_l_a32(uint32_t fetchdat) \ + { \ + fetchdat = fastreadl(cs + cpu_state.pc); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.pc++; \ + \ + cpu_state.ea_seg = &seg; \ + cpu_state.ssegs = 1; \ + CLOCK_CYCLES(4); \ + PREFETCH_PREFIX(); \ + \ + if (opcode_table[(fetchdat & 0xff) | 0x300]) \ + return opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ -} + } op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) @@ -84,78 +88,89 @@ op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) -static int op_66(uint32_t fetchdat) /*Data size select*/ + static int op_66(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67(uint32_t fetchdat) /*Address size select*/ +static int +op_67(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_66_REPE(uint32_t fetchdat) /*Data size select*/ +static int +op_66_REPE(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67_REPE(uint32_t fetchdat) /*Address size select*/ +static int +op_67_REPE(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_66_REPNE(uint32_t fetchdat) /*Data size select*/ +static int +op_66_REPNE(uint32_t fetchdat) /*Data size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x100) ^ 0x100) | (cpu_state.op32 & 0x200); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int op_67_REPNE(uint32_t fetchdat) /*Address size select*/ +static int +op_67_REPNE(uint32_t fetchdat) /*Address size select*/ { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + cpu_state.op32 = ((use32 & 0x200) ^ 0x200) | (cpu_state.op32 & 0x100); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_rep.h b/src/cpu/x86_ops_rep.h index ffae30e09..67bd8433d 100644 --- a/src/cpu/x86_ops_rep.h +++ b/src/cpu/x86_ops_rep.h @@ -1,768 +1,883 @@ -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64 = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - high_page = 0; \ - do_mmut_wb(es, DEST_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - temp = inb(DX); \ - writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - high_page = 0; \ - do_mmut_ww(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - high_page = 0; \ - do_mmut_wl(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - reads++; writes++; total_cycles += 15; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - reads++; writes++; total_cycles += 14; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64 = addr64_2 = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_ww(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_wl(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - reads++; writes++; total_cycles += is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int writes = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - writes++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - reads++; total_cycles += is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + reads++; \ + writes++; \ + total_cycles += 15; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + reads++; \ + writes++; \ + total_cycles += 14; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + reads++; \ + writes++; \ + total_cycles += is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, writes, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int writes = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + writes++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, 0, 0, writes, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + reads++; \ + total_cycles += is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } #define CHEK_READ(a, b, c) - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64 = addr64_2 = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = uncached = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb2(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = uncached = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = uncached = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - reads += 2; total_cycles += is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int reads = 0, total_cycles = 0, tempz; \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - reads++; total_cycles += is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + reads += 2; \ + total_cycles += is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, reads, 0, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int reads = 0, total_cycles = 0, tempz; \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + reads++; \ + total_cycles += is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + PREFETCH_RUN(total_cycles, 1, -1, 0, reads, 0, 0, 0); \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } REP_OPS(a16, CX, SI, DI) REP_OPS(a32, ECX, ESI, EDI) REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) -static int opREPNE(uint32_t fetchdat) +static int +opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int opREPE(uint32_t fetchdat) +static int +opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - PREFETCH_PREFIX(); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + PREFETCH_PREFIX(); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_rep_dyn.h b/src/cpu/x86_ops_rep_dyn.h index e63ed32fe..576baa403 100644 --- a/src/cpu/x86_ops_rep_dyn.h +++ b/src/cpu/x86_ops_rep_dyn.h @@ -1,703 +1,788 @@ -#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ -static int opREP_INSB_ ## size(uint32_t fetchdat) \ -{ \ - addr64 = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - high_page = 0; \ - do_mmut_wb(es, DEST_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - temp = inb(DX); \ - writememb_n(es, DEST_REG, addr64, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSW_ ## size(uint32_t fetchdat) \ -{ \ - addr64a[0] = addr64a[1] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - high_page = 0; \ - do_mmut_ww(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inw(DX); \ - writememw_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_INSL_ ## size(uint32_t fetchdat) \ -{ \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - high_page = 0; \ - do_mmut_wl(es, DEST_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - temp = inl(DX); \ - writememl_n(es, DEST_REG, addr64a, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= 15; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_OUTSB_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint8_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - temp = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - outb(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSW_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint16_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - temp = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - outw(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_OUTSL_ ## size(uint32_t fetchdat) \ -{ \ - if (CNT_REG > 0) \ - { \ - uint32_t temp; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - temp = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - check_io_perm(DX); \ - check_io_perm(DX+1); \ - check_io_perm(DX+2); \ - check_io_perm(DX+3); \ - outl(DX, temp); \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= 14; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_MOVSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64 = addr64_2 = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint8_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64) ; \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_wb(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) break; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - writememb_n(es, DEST_REG, addr64_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint16_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_ww(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememw_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_MOVSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - } \ - while (CNT_REG > 0) \ - { \ - uint32_t temp; \ - \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) break; \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_wl(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) break; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - writememl_n(es, DEST_REG, addr64a_2, temp); if (cpu_state.abrt) return 1; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 3 : 4; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ - \ -static int opREP_STOSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - writememb(es, DEST_REG, AL); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - writememw(es, DEST_REG, AX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_STOSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_WRITE(&cpu_state.seg_es); \ - while (CNT_REG > 0) \ - { \ - CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - writememl(es, DEST_REG, EAX); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_LODSB_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - AL = readmemb(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG--; \ - else SRC_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSW_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - AX = readmemw(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 2; \ - else SRC_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_LODSL_ ## size(uint32_t fetchdat) \ -{ \ - int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - if (CNT_REG > 0) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - while (CNT_REG > 0) \ - { \ - CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); if (cpu_state.abrt) return 1; \ - if (cpu_state.flags & D_FLAG) SRC_REG -= 4; \ - else SRC_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 4 : 5; \ - if (cycles < cycles_end) \ - break; \ - } \ - if (CNT_REG > 0) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - +#define REP_OPS(size, CNT_REG, SRC_REG, DEST_REG) \ + static int opREP_INSB_##size(uint32_t fetchdat) \ + { \ + addr64 = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + high_page = 0; \ + do_mmut_wb(es, DEST_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inb(DX); \ + writememb_n(es, DEST_REG, addr64, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSW_##size(uint32_t fetchdat) \ + { \ + addr64a[0] = addr64a[1] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + high_page = 0; \ + do_mmut_ww(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inw(DX); \ + writememw_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_INSL_##size(uint32_t fetchdat) \ + { \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + high_page = 0; \ + do_mmut_wl(es, DEST_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + temp = inl(DX); \ + writememl_n(es, DEST_REG, addr64a, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= 15; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_OUTSB_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint8_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + outb(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSW_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint16_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + outw(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_OUTSL_##size(uint32_t fetchdat) \ + { \ + if (CNT_REG > 0) { \ + uint32_t temp; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + check_io_perm(DX); \ + check_io_perm(DX + 1); \ + check_io_perm(DX + 2); \ + check_io_perm(DX + 3); \ + outl(DX, temp); \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= 14; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_MOVSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64 = addr64_2 = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint8_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_wb(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + writememb_n(es, DEST_REG, addr64_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint16_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_ww(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememw_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_MOVSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + } \ + while (CNT_REG > 0) { \ + uint32_t temp; \ + \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + break; \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_wl(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + break; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + writememl_n(es, DEST_REG, addr64a_2, temp); \ + if (cpu_state.abrt) \ + return 1; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 3 : 4; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_STOSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + writememb(es, DEST_REG, AL); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + writememw(es, DEST_REG, AX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_STOSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_WRITE(&cpu_state.seg_es); \ + while (CNT_REG > 0) { \ + CHECK_WRITE_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + writememl(es, DEST_REG, EAX); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_LODSB_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + AL = readmemb(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG--; \ + else \ + SRC_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSW_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + AX = readmemw(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 2; \ + else \ + SRC_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_LODSL_##size(uint32_t fetchdat) \ + { \ + int cycles_end = cycles - ((is386 && cpu_use_dynarec) ? 1000 : 100); \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + if (CNT_REG > 0) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + while (CNT_REG > 0) { \ + CHECK_READ_REP(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + EAX = readmeml(cpu_state.ea_seg->base, SRC_REG); \ + if (cpu_state.abrt) \ + return 1; \ + if (cpu_state.flags & D_FLAG) \ + SRC_REG -= 4; \ + else \ + SRC_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 4 : 5; \ + if (cycles < cycles_end) \ + break; \ + } \ + if (CNT_REG > 0) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } #define CHEK_READ(a, b, c) - -#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ -static int opREP_CMPSB_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64 = addr64_2 = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint8_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ - high_page = uncached = 0; \ - do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - do_mmut_rb2(es, DEST_REG, &addr64_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemb_n(es, DEST_REG, addr64_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG--; SRC_REG--; } \ - else { DEST_REG++; SRC_REG++; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub8(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSW_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64a[0] = addr64a[1] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint16_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ - high_page = uncached = 0; \ - do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - do_mmut_rw2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmemw_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 2; SRC_REG -= 2; } \ - else { DEST_REG += 2; SRC_REG += 2; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub16(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_CMPSL_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - \ - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ - \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - uint32_t temp, temp2; \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ - high_page = uncached = 0; \ - do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ - if (cpu_state.abrt) return 1; \ - CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - do_mmut_rl2(es, DEST_REG, addr64a_2); \ - if (cpu_state.abrt) return 1; \ - temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = old_rl2; \ - temp2 = readmeml_n(es, DEST_REG, addr64a_2); if (cpu_state.abrt) return 1; \ - if (uncached) \ - readlookup2[(uint32_t)(es+DEST_REG)>>12] = (uintptr_t) LOOKUP_INV; \ - \ - if (cpu_state.flags & D_FLAG) { DEST_REG -= 4; SRC_REG -= 4; } \ - else { DEST_REG += 4; SRC_REG += 4; } \ - CNT_REG--; \ - cycles -= is486 ? 7 : 9; \ - setsub32(temp, temp2); \ - tempz = (ZF_SET()) ? 1 : 0; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ - \ -static int opREP_SCASB_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ - uint8_t temp = readmemb(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub8(AL, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG--; \ - else DEST_REG++; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASW_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ - uint16_t temp = readmemw(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub16(AX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 2; \ - else DEST_REG += 2; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} \ -static int opREP_SCASL_ ## size(uint32_t fetchdat) \ -{ \ - int tempz; \ - int cycles_end = cycles - 1000; \ - if (trap) \ - cycles_end = cycles+1; /*Force the instruction to end after only one iteration when trap flag set*/ \ - tempz = FV; \ - if ((CNT_REG > 0) && (FV == tempz)) \ - SEG_CHECK_READ(&cpu_state.seg_es); \ - while ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ - uint32_t temp = readmeml(es, DEST_REG); if (cpu_state.abrt) break;\ - setsub32(EAX, temp); \ - tempz = (ZF_SET()) ? 1 : 0; \ - if (cpu_state.flags & D_FLAG) DEST_REG -= 4; \ - else DEST_REG += 4; \ - CNT_REG--; \ - cycles -= is486 ? 5 : 8; \ - if (cycles < cycles_end) \ - break; \ - } \ - if ((CNT_REG > 0) && (FV == tempz)) \ - { \ - CPU_BLOCK_END(); \ - cpu_state.pc = cpu_state.oldpc; \ - return 1; \ - } \ - return cpu_state.abrt; \ -} +#define REP_OPS_CMPS_SCAS(size, CNT_REG, SRC_REG, DEST_REG, FV) \ + static int opREP_CMPSB_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64 = addr64_2 = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint8_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG); \ + high_page = uncached = 0; \ + do_mmut_rb(cpu_state.ea_seg->base, SRC_REG, &addr64); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + do_mmut_rb2(es, DEST_REG, &addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemb_n(cpu_state.ea_seg->base, SRC_REG, addr64); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemb_n(es, DEST_REG, addr64_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG--; \ + SRC_REG--; \ + } else { \ + DEST_REG++; \ + SRC_REG++; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub8(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSW_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64a[0] = addr64a[1] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint16_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 1UL); \ + high_page = uncached = 0; \ + do_mmut_rw(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + do_mmut_rw2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmemw_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmemw_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 2; \ + SRC_REG -= 2; \ + } else { \ + DEST_REG += 2; \ + SRC_REG += 2; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub16(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_CMPSL_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + \ + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; \ + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; \ + \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + uint32_t temp, temp2; \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + CHECK_READ(cpu_state.ea_seg, SRC_REG, SRC_REG + 3UL); \ + high_page = uncached = 0; \ + do_mmut_rl(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + CHECK_READ(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + do_mmut_rl2(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + temp = readmeml_n(cpu_state.ea_seg->base, SRC_REG, addr64a); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = old_rl2; \ + temp2 = readmeml_n(es, DEST_REG, addr64a_2); \ + if (cpu_state.abrt) \ + return 1; \ + if (uncached) \ + readlookup2[(uint32_t) (es + DEST_REG) >> 12] = (uintptr_t) LOOKUP_INV; \ + \ + if (cpu_state.flags & D_FLAG) { \ + DEST_REG -= 4; \ + SRC_REG -= 4; \ + } else { \ + DEST_REG += 4; \ + SRC_REG += 4; \ + } \ + CNT_REG--; \ + cycles -= is486 ? 7 : 9; \ + setsub32(temp, temp2); \ + tempz = (ZF_SET()) ? 1 : 0; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + \ + static int opREP_SCASB_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG); \ + uint8_t temp = readmemb(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub8(AL, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG--; \ + else \ + DEST_REG++; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASW_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \ + uint16_t temp = readmemw(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub16(AX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 2; \ + else \ + DEST_REG += 2; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } \ + static int opREP_SCASL_##size(uint32_t fetchdat) \ + { \ + int tempz; \ + int cycles_end = cycles - 1000; \ + if (trap) \ + cycles_end = cycles + 1; /*Force the instruction to end after only one iteration when trap flag set*/ \ + tempz = FV; \ + if ((CNT_REG > 0) && (FV == tempz)) \ + SEG_CHECK_READ(&cpu_state.seg_es); \ + while ((CNT_REG > 0) && (FV == tempz)) { \ + CHECK_READ_REP(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \ + uint32_t temp = readmeml(es, DEST_REG); \ + if (cpu_state.abrt) \ + break; \ + setsub32(EAX, temp); \ + tempz = (ZF_SET()) ? 1 : 0; \ + if (cpu_state.flags & D_FLAG) \ + DEST_REG -= 4; \ + else \ + DEST_REG += 4; \ + CNT_REG--; \ + cycles -= is486 ? 5 : 8; \ + if (cycles < cycles_end) \ + break; \ + } \ + if ((CNT_REG > 0) && (FV == tempz)) { \ + CPU_BLOCK_END(); \ + cpu_state.pc = cpu_state.oldpc; \ + return 1; \ + } \ + return cpu_state.abrt; \ + } REP_OPS(a16, CX, SI, DI) REP_OPS(a32, ECX, ESI, EDI) REP_OPS_CMPS_SCAS(a16_NE, CX, SI, DI, 0) -REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) +REP_OPS_CMPS_SCAS(a16_E, CX, SI, DI, 1) REP_OPS_CMPS_SCAS(a32_NE, ECX, ESI, EDI, 0) -REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) +REP_OPS_CMPS_SCAS(a32_E, ECX, ESI, EDI, 1) -static int opREPNE(uint32_t fetchdat) +static int +opREPNE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + if (x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPNE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } -static int opREPE(uint32_t fetchdat) +static int +opREPE(uint32_t fetchdat) { - fetchdat = fastreadl(cs + cpu_state.pc); - if (cpu_state.abrt) return 1; - cpu_state.pc++; + fetchdat = fastreadl(cs + cpu_state.pc); + if (cpu_state.abrt) + return 1; + cpu_state.pc++; - CLOCK_CYCLES(2); - if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) - return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + CLOCK_CYCLES(2); + if (x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32]) + return x86_opcodes_REPE[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + return x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); } diff --git a/src/cpu/x86_ops_ret.h b/src/cpu/x86_ops_ret.h index 693fb0393..ec200f2d7 100644 --- a/src/cpu/x86_ops_ret.h +++ b/src/cpu/x86_ops_ret.h @@ -1,311 +1,291 @@ #ifdef USE_NEW_DYNAREC -#define CPU_SET_OXPC +# define CPU_SET_OXPC #else -#define CPU_SET_OXPC oxpc = cpu_state.pc; +# define CPU_SET_OXPC oxpc = cpu_state.pc; #endif -#define RETF_a16(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(0, stack_offset); \ - return 1; \ - } \ - CPU_SET_OXPC \ - if (stack32) \ - { \ - cpu_state.pc = readmemw(ss, ESP); \ - loadcs(readmemw(ss, ESP + 2)); \ - } \ - else \ - { \ - cpu_state.pc = readmemw(ss, SP); \ - loadcs(readmemw(ss, SP + 2)); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 4 + stack_offset; \ - else SP += 4 + stack_offset; \ - cycles -= timing_retf_rm; +#define RETF_a16(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(0, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmemw(ss, ESP); \ + loadcs(readmemw(ss, ESP + 2)); \ + } else { \ + cpu_state.pc = readmemw(ss, SP); \ + loadcs(readmemw(ss, SP + 2)); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 4 + stack_offset; \ + else \ + SP += 4 + stack_offset; \ + cycles -= timing_retf_rm; -#define RETF_a32(stack_offset) \ - if ((msw&1) && !(cpu_state.eflags&VM_FLAG)) \ - { \ - pmoderetf(1, stack_offset); \ - return 1; \ - } \ - CPU_SET_OXPC \ - if (stack32) \ - { \ - cpu_state.pc = readmeml(ss, ESP); \ - loadcs(readmeml(ss, ESP + 4) & 0xffff); \ - } \ - else \ - { \ - cpu_state.pc = readmeml(ss, SP); \ - loadcs(readmeml(ss, SP + 4) & 0xffff); \ - } \ - if (cpu_state.abrt) return 1; \ - if (stack32) ESP += 8 + stack_offset; \ - else SP += 8 + stack_offset; \ - cycles -= timing_retf_rm; +#define RETF_a32(stack_offset) \ + if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { \ + pmoderetf(1, stack_offset); \ + return 1; \ + } \ + CPU_SET_OXPC \ + if (stack32) { \ + cpu_state.pc = readmeml(ss, ESP); \ + loadcs(readmeml(ss, ESP + 4) & 0xffff); \ + } else { \ + cpu_state.pc = readmeml(ss, SP); \ + loadcs(readmeml(ss, SP + 4) & 0xffff); \ + } \ + if (cpu_state.abrt) \ + return 1; \ + if (stack32) \ + ESP += 8 + stack_offset; \ + else \ + SP += 8 + stack_offset; \ + cycles -= timing_retf_rm; -static int opRETF_a16(uint32_t fetchdat) +static int +opRETF_a16(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(0); + CPU_BLOCK_END(); + RETF_a16(0); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a32(uint32_t fetchdat) +static int +opRETF_a32(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(0); + CPU_BLOCK_END(); + RETF_a32(0); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a16_imm(uint32_t fetchdat) +static int +opRETF_a16_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a16(offset); + CPU_BLOCK_END(); + RETF_a16(offset); - PREFETCH_RUN(cycles_old-cycles, 3, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 3, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return 0; } -static int opRETF_a32_imm(uint32_t fetchdat) +static int +opRETF_a32_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int cycles_old = cycles; UN_USED(cycles_old); + uint16_t offset = getwordf(); + int cycles_old = cycles; + UN_USED(cycles_old); - CPU_BLOCK_END(); - RETF_a32(offset); + CPU_BLOCK_END(); + RETF_a32(offset); - PREFETCH_RUN(cycles_old-cycles, 3, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return 0; + PREFETCH_RUN(cycles_old - cycles, 3, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return 0; } -static int opIRET_186(uint32_t fetchdat) +static int +opIRET_186(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET_286(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; +} + +static int +opIRET(uint32_t fetchdat) +{ + int cycles_old = cycles; + UN_USED(cycles_old); + + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + if (cr4 & CR4_VME) { + uint16_t new_pc, new_cs, new_flags; + + new_pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + new_flags = readmemw(ss, ((SP + 4) & 0xffff)); + if (cpu_state.abrt) return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRET_286(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf(NULL,0); + if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) { + x86gpf(NULL, 0); return 1; - } - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (cpu_state.flags & 0x7000) | (readmemw(ss, ((SP + 4) & 0xffff)) & 0x0fd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + } + SP += 6; + if (new_flags & I_FLAG) + cpu_state.eflags |= VIF_FLAG; + else + cpu_state.eflags &= ~VIF_FLAG; + cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; + loadcs(new_cs); + cpu_state.pc = new_pc; - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; + cycles -= timing_iret_rm; + } else { + x86gpf_expected(NULL, 0); + return 1; + } + } else { + if (msw & 1) { + optype = IRET; + pmodeiret(0); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmemw(ss, ESP); + new_cs = readmemw(ss, ESP + 2); + cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; + ESP += 6; + } else { + cpu_state.pc = readmemw(ss, SP); + new_cs = readmemw(ss, ((SP + 2) & 0xffff)); + cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; + SP += 6; + } + loadcs(new_cs); + cycles -= timing_iret_rm; + } + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); + + PREFETCH_RUN(cycles_old - cycles, 1, -1, 2, 0, 0, 0, 0); + PREFETCH_FLUSH(); + return cpu_state.abrt; } -static int opIRET(uint32_t fetchdat) +static int +opIRETD(uint32_t fetchdat) { - int cycles_old = cycles; UN_USED(cycles_old); + int cycles_old = cycles; + UN_USED(cycles_old); - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - if (cr4 & CR4_VME) - { - uint16_t new_pc, new_cs, new_flags; - - new_pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - new_flags = readmemw(ss, ((SP + 4) & 0xffff)); - if (cpu_state.abrt) - return 1; - - if ((new_flags & T_FLAG) || ((new_flags & I_FLAG) && (cpu_state.eflags & VIP_FLAG))) - { - x86gpf(NULL, 0); - return 1; - } - SP += 6; - if (new_flags & I_FLAG) - cpu_state.eflags |= VIF_FLAG; - else - cpu_state.eflags &= ~VIF_FLAG; - cpu_state.flags = (cpu_state.flags & 0x3300) | (new_flags & 0x4cd5) | 2; - loadcs(new_cs); - cpu_state.pc = new_pc; - - cycles -= timing_iret_rm; - } - else - { - x86gpf_expected(NULL,0); - return 1; - } + if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) { + x86gpf_expected(NULL, 0); + return 1; + } + if (msw & 1) { + optype = IRET; + pmodeiret(1); + optype = 0; + } else { + uint16_t new_cs; + CPU_SET_OXPC + if (stack32) { + cpu_state.pc = readmeml(ss, ESP); + new_cs = readmemw(ss, ESP + 4); + cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, ESP + 10); + ESP += 12; + } else { + cpu_state.pc = readmeml(ss, SP); + new_cs = readmemw(ss, ((SP + 4) & 0xffff)); + cpu_state.flags = (readmemw(ss, (SP + 8) & 0xffff) & 0xffd5) | 2; + cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); + SP += 12; } - else - { - if (msw&1) - { - optype = IRET; - pmodeiret(0); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmemw(ss, ESP); - new_cs = readmemw(ss, ESP + 2); - cpu_state.flags = (readmemw(ss, ESP + 4) & 0xffd5) | 2; - ESP += 6; - } - else - { - cpu_state.pc = readmemw(ss, SP); - new_cs = readmemw(ss, ((SP + 2) & 0xffff)); - cpu_state.flags = (readmemw(ss, ((SP + 4) & 0xffff)) & 0xffd5) | 2; - SP += 6; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); + loadcs(new_cs); + cycles -= timing_iret_rm; + } + flags_extract(); + nmi_enable = 1; + CPU_BLOCK_END(); - PREFETCH_RUN(cycles_old-cycles, 1, -1, 2,0,0,0, 0); - PREFETCH_FLUSH(); - return cpu_state.abrt; -} - -static int opIRETD(uint32_t fetchdat) -{ - int cycles_old = cycles; UN_USED(cycles_old); - - if ((cr0 & 1) && (cpu_state.eflags & VM_FLAG) && (IOPL != 3)) - { - x86gpf_expected(NULL,0); - return 1; - } - if (msw & 1) - { - optype = IRET; - pmodeiret(1); - optype = 0; - } - else - { - uint16_t new_cs; - CPU_SET_OXPC - if (stack32) - { - cpu_state.pc = readmeml(ss, ESP); - new_cs = readmemw(ss, ESP + 4); - cpu_state.flags = (readmemw(ss, ESP + 8) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, ESP + 10); - ESP += 12; - } - else - { - cpu_state.pc = readmeml(ss, SP); - new_cs = readmemw(ss, ((SP + 4) & 0xffff)); - cpu_state.flags = (readmemw(ss,(SP + 8) & 0xffff) & 0xffd5) | 2; - cpu_state.eflags = readmemw(ss, (SP + 10) & 0xffff); - SP += 12; - } - loadcs(new_cs); - cycles -= timing_iret_rm; - } - flags_extract(); - nmi_enable = 1; - CPU_BLOCK_END(); - - PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,2,0,0, 1); - PREFETCH_FLUSH(); - return cpu_state.abrt; + PREFETCH_RUN(cycles_old - cycles, 1, -1, 0, 2, 0, 0, 1); + PREFETCH_FLUSH(); + return cpu_state.abrt; } diff --git a/src/cpu/x86_ops_set.h b/src/cpu/x86_ops_set.h index f6fd50e69..4d2a98bcb 100644 --- a/src/cpu/x86_ops_set.h +++ b/src/cpu/x86_ops_set.h @@ -1,23 +1,23 @@ -#define opSET(condition) \ - static int opSET ## condition ## _a16(uint32_t fetchdat) \ - { \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } \ - \ - static int opSET ## condition ## _a32(uint32_t fetchdat) \ - { \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - seteab((cond_ ## condition) ? 1 : 0); \ - CLOCK_CYCLES(4); \ - return cpu_state.abrt; \ - } +#define opSET(condition) \ + static int opSET##condition##_a16(uint32_t fetchdat) \ + { \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } \ + \ + static int opSET##condition##_a32(uint32_t fetchdat) \ + { \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + seteab((cond_##condition) ? 1 : 0); \ + CLOCK_CYCLES(4); \ + return cpu_state.abrt; \ + } opSET(O) opSET(NO) diff --git a/src/cpu/x86_ops_shift.h b/src/cpu/x86_ops_shift.h index 5d03cb9a9..bba8e24f7 100644 --- a/src/cpu/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -1,850 +1,1052 @@ #ifdef USE_NEW_DYNAREC -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR8, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR8, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t) temp >> c; \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR16, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR16, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t) temp >> c; \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROL32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_rotate(FLAGS_ROR32, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ +# define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROL32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_rotate(FLAGS_ROR32, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL l, c*/ \ + seteal(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t) temp >> c; \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + } \ } #else -#define OP_SHIFT_b(c, ea32) \ - { \ - uint8_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL b, c*/ \ - temp = (temp << (c & 7)) | (temp >> (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 7)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR b,CL*/ \ - temp = (temp >> (c & 7)) | (temp << (8-(c & 7))); \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR b,CL*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteab(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL b,CL*/ \ - seteab(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR b,CL*/ \ - seteab(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR b,CL*/ \ - temp = (int8_t)temp >> c; \ - seteab(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_b(c, ea32) \ + { \ + uint8_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL b, c*/ \ + temp = (temp << (c & 7)) | (temp >> (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 7)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR b,CL*/ \ + temp = (temp >> (c & 7)) | (temp << (8 - (c & 7))); \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 7)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR b,CL*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL b,CL*/ \ + seteab(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL8, temp_orig, c, (temp << c) & 0xff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR b,CL*/ \ + seteab(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR8, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR b,CL*/ \ + temp = (int8_t) temp >> c; \ + seteab(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR8, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_w(c, ea32) \ - { \ - uint16_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL w, c*/ \ - temp = (temp << (c & 15)) | (temp >> (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 15)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR w,CL*/ \ - temp = (temp >> (c & 15)) | (temp << (16-(c & 15))); \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x8000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x8000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x18: /*RCR w, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x8000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x4000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL w, c*/ \ - seteaw(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x28: /*SHR w, c*/ \ - seteaw(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x38: /*SAR w, c*/ \ - temp = (int16_t)temp >> c; \ - seteaw(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - } \ +# define OP_SHIFT_w(c, ea32) \ + { \ + uint16_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL w, c*/ \ + temp = (temp << (c & 15)) | (temp >> (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 15)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR w,CL*/ \ + temp = (temp >> (c & 15)) | (temp << (16 - (c & 15))); \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x8000) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x8000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 15)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x18: /*RCR w, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x8000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x4000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL w, c*/ \ + seteaw(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL16, temp_orig, c, (temp << c) & 0xffff); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x28: /*SHR w, c*/ \ + seteaw(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR16, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x38: /*SAR w, c*/ \ + temp = (int16_t) temp >> c; \ + seteaw(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR16, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + } \ } -#define OP_SHIFT_l(c, ea32) \ - { \ - uint32_t temp_orig = temp; \ - if (!c) return 0; \ - flags_rebuild(); \ - switch (rmdat & 0x38) \ - { \ - case 0x00: /*ROL l, c*/ \ - temp = (temp << c) | (temp >> (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 1) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 31)) & 1) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x08: /*ROR l,CL*/ \ - temp = (temp >> c) | (temp << (32-c)); \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp & 0x80000000) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, ea32); \ - break; \ - case 0x10: /*RCL l, c*/ \ - temp2 = CF_SET(); \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 1 : 0; \ - temp2 = temp & 0x80000000; \ - temp = (temp << 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x18: /*RCR l, c*/ \ - temp2 = cpu_state.flags & C_FLAG; \ - if (is486) CLOCK_CYCLES_ALWAYS(c); \ - while (c > 0) \ - { \ - tempc = temp2 ? 0x80000000 : 0; \ - temp2 = temp & 1; \ - temp = (temp >> 1) | tempc; \ - c--; \ - } \ - seteal(temp); if (cpu_state.abrt) return 1; \ - cpu_state.flags &= ~(C_FLAG | V_FLAG); \ - if (temp2) cpu_state.flags |= C_FLAG; \ - if ((temp ^ (temp >> 1)) & 0x40000000) cpu_state.flags |= V_FLAG; \ - CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ - PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x20: case 0x30: /*SHL l, c*/ \ - seteal(temp << c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x28: /*SHR l, c*/ \ - seteal(temp >> c); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - case 0x38: /*SAR l, c*/ \ - temp = (int32_t)temp >> c; \ - seteal(temp); if (cpu_state.abrt) return 1; \ - set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ - PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, ea32); \ - break; \ - } \ +# define OP_SHIFT_l(c, ea32) \ + { \ + uint32_t temp_orig = temp; \ + if (!c) \ + return 0; \ + flags_rebuild(); \ + switch (rmdat & 0x38) { \ + case 0x00: /*ROL l, c*/ \ + temp = (temp << c) | (temp >> (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 1) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 31)) & 1) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x08: /*ROR l,CL*/ \ + temp = (temp >> c) | (temp << (32 - c)); \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp & 0x80000000) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, ea32); \ + break; \ + case 0x10: /*RCL l, c*/ \ + temp2 = CF_SET(); \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 1 : 0; \ + temp2 = temp & 0x80000000; \ + temp = (temp << 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((cpu_state.flags & C_FLAG) ^ (temp >> 31)) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x18: /*RCR l, c*/ \ + temp2 = cpu_state.flags & C_FLAG; \ + if (is486) \ + CLOCK_CYCLES_ALWAYS(c); \ + while (c > 0) { \ + tempc = temp2 ? 0x80000000 : 0; \ + temp2 = temp & 1; \ + temp = (temp >> 1) | tempc; \ + c--; \ + } \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.flags &= ~(C_FLAG | V_FLAG); \ + if (temp2) \ + cpu_state.flags |= C_FLAG; \ + if ((temp ^ (temp >> 1)) & 0x40000000) \ + cpu_state.flags |= V_FLAG; \ + CLOCK_CYCLES((cpu_mod == 3) ? 9 : 10); \ + PREFETCH_RUN((cpu_mod == 3) ? 9 : 10, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x20: \ + case 0x30: /*SHL l, c*/ \ + seteal(temp << c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHL32, temp_orig, c, temp << c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x28: /*SHR l, c*/ \ + seteal(temp >> c); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SHR32, temp_orig, c, temp >> c); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + case 0x38: /*SAR l, c*/ \ + temp = (int32_t) temp >> c; \ + seteal(temp); \ + if (cpu_state.abrt) \ + return 1; \ + set_flags_shift(FLAGS_SAR32, temp_orig, c, temp); \ + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 7); \ + PREFETCH_RUN((cpu_mod == 3) ? 3 : 7, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, ea32); \ + break; \ + } \ } #endif -static int opC0_a16(uint32_t fetchdat) +static int +opC0_a16(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opC0_a32(uint32_t fetchdat) +static int +opC0_a32(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opC1_w_a16(uint32_t fetchdat) +static int +opC1_w_a16(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opC1_w_a32(uint32_t fetchdat) +static int +opC1_w_a32(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opC1_l_a16(uint32_t fetchdat) +static int +opC1_l_a16(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opC1_l_a32(uint32_t fetchdat) +static int +opC1_l_a32(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = readmemb(cs, cpu_state.pc) & 31; cpu_state.pc++; - PREFETCH_PREFIX(); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = readmemb(cs, cpu_state.pc) & 31; + cpu_state.pc++; + PREFETCH_PREFIX(); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -static int opD0_a16(uint32_t fetchdat) +static int +opD0_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; + int c = 1; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opD0_a32(uint32_t fetchdat) +static int +opD0_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint8_t temp, temp2 = 0; + int c = 1; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opD1_w_a16(uint32_t fetchdat) +static int +opD1_w_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; + int c = 1; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opD1_w_a32(uint32_t fetchdat) +static int +opD1_w_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint16_t temp, temp2 = 0; + int c = 1; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opD1_l_a16(uint32_t fetchdat) +static int +opD1_l_a16(uint32_t fetchdat) { - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; + int c = 1; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opD1_l_a32(uint32_t fetchdat) +static int +opD1_l_a32(uint32_t fetchdat) { - int c = 1; - int tempc; - uint32_t temp, temp2 = 0; + int c = 1; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } -static int opD2_a16(uint32_t fetchdat) +static int +opD2_a16(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 0); + return 0; } -static int opD2_a32(uint32_t fetchdat) +static int +opD2_a32(uint32_t fetchdat) { - int c; - int tempc; - uint8_t temp, temp2 = 0; + int c; + int tempc; + uint8_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteab(); if (cpu_state.abrt) return 1; - OP_SHIFT_b(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteab(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_b(c, 1); + return 0; } -static int opD3_w_a16(uint32_t fetchdat) +static int +opD3_w_a16(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 0); + return 0; } -static int opD3_w_a32(uint32_t fetchdat) +static int +opD3_w_a32(uint32_t fetchdat) { - int c; - int tempc; - uint16_t temp, temp2 = 0; + int c; + int tempc; + uint16_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteaw(); if (cpu_state.abrt) return 1; - OP_SHIFT_w(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteaw(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_w(c, 1); + return 0; } -static int opD3_l_a16(uint32_t fetchdat) +static int +opD3_l_a16(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 0); + return 0; } -static int opD3_l_a32(uint32_t fetchdat) +static int +opD3_l_a32(uint32_t fetchdat) { - int c; - int tempc; - uint32_t temp, temp2 = 0; + int c; + int tempc; + uint32_t temp, temp2 = 0; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - c = CL & 31; - temp = geteal(); if (cpu_state.abrt) return 1; - OP_SHIFT_l(c, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + c = CL & 31; + temp = geteal(); + if (cpu_state.abrt) + return 1; + OP_SHIFT_l(c, 1); + return 0; } - -#define SHLD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ - if (count <= 16) tempw = templ >> (16 - count); \ - else tempw = (templ << count) >> 16; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } +#define SHLD_w() \ + if (count) { \ + int tempc; \ + uint32_t templ; \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ + templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ + if (count <= 16) \ + tempw = templ >> (16 - count); \ + else \ + tempw = (templ << count) >> 16; \ + seteaw(tempw); \ + if (cpu_state.abrt) \ + return 1; \ + setznp16(tempw); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } #define SHLD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ - templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } + if (count) { \ + int tempc; \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ + templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ + seteal(templ); \ + if (cpu_state.abrt) \ + return 1; \ + setznp32(templ); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } - -#define SHRD_w() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ; \ - uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - tempc = (tempw >> (count - 1)) & 1; \ - templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ - tempw = templ >> count; \ - seteaw(tempw); if (cpu_state.abrt) return 1; \ - setznp16(tempw); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } +#define SHRD_w() \ + if (count) { \ + int tempc; \ + uint32_t templ; \ + uint16_t tempw = geteaw(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (tempw >> (count - 1)) & 1; \ + templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ + tempw = templ >> count; \ + seteaw(tempw); \ + if (cpu_state.abrt) \ + return 1; \ + setznp16(tempw); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } #define SHRD_l() \ - if (count) \ - { \ - int tempc; \ - uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - tempc = (templ >> (count - 1)) & 1; \ - templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ - seteal(templ); if (cpu_state.abrt) return 1; \ - setznp32(templ); \ - flags_rebuild(); \ - if (tempc) cpu_state.flags |= C_FLAG; \ - } + if (count) { \ + int tempc; \ + uint32_t templ = geteal(); \ + if (cpu_state.abrt) \ + return 1; \ + tempc = (templ >> (count - 1)) & 1; \ + templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ + seteal(templ); \ + if (cpu_state.abrt) \ + return 1; \ + setznp32(templ); \ + flags_rebuild(); \ + if (tempc) \ + cpu_state.flags |= C_FLAG; \ + } -#define opSHxD(operation) \ - static int op ## operation ## _i_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _CL_a16(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_16(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ - return 0; \ - } \ - static int op ## operation ## _i_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = getbyte() & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } \ - static int op ## operation ## _CL_a32(uint32_t fetchdat) \ - { \ - int count; \ - \ - fetch_ea_32(fetchdat); \ - if (cpu_mod != 3) \ - SEG_CHECK_WRITE(cpu_state.ea_seg); \ - count = CL & 31; \ - operation(); \ - \ - CLOCK_CYCLES(3); \ - PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ - return 0; \ - } +#define opSHxD(operation) \ + static int op##operation##_i_a16(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = getbyte() & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); \ + return 0; \ + } \ + static int op##operation##_CL_a16(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_16(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = CL & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); \ + return 0; \ + } \ + static int op##operation##_i_a32(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = getbyte() & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); \ + return 0; \ + } \ + static int op##operation##_CL_a32(uint32_t fetchdat) \ + { \ + int count; \ + \ + fetch_ea_32(fetchdat); \ + if (cpu_mod != 3) \ + SEG_CHECK_WRITE(cpu_state.ea_seg); \ + count = CL & 31; \ + operation(); \ + \ + CLOCK_CYCLES(3); \ + PREFETCH_RUN(3, 3, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); \ + return 0; \ + } opSHxD(SHLD_w) opSHxD(SHLD_l) diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 58f24c6f9..374dad9f4 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -1,38 +1,38 @@ -#define PUSH_W_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_W(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } +#define PUSH_W_OP(reg) \ + static int opPUSH_##reg(uint32_t fetchdat) \ + { \ + PUSH_W(reg); \ + CLOCK_CYCLES((is486) ? 1 : 2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } -#define PUSH_L_OP(reg) \ - static int opPUSH_ ## reg (uint32_t fetchdat) \ - { \ - PUSH_L(reg); \ - CLOCK_CYCLES((is486) ? 1 : 2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } +#define PUSH_L_OP(reg) \ + static int opPUSH_##reg(uint32_t fetchdat) \ + { \ + PUSH_L(reg); \ + CLOCK_CYCLES((is486) ? 1 : 2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \ + return cpu_state.abrt; \ + } -#define POP_W_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_W(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); \ - return cpu_state.abrt; \ - } +#define POP_W_OP(reg) \ + static int opPOP_##reg(uint32_t fetchdat) \ + { \ + reg = POP_W(); \ + CLOCK_CYCLES((is486) ? 1 : 4); \ + PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); \ + return cpu_state.abrt; \ + } -#define POP_L_OP(reg) \ - static int opPOP_ ## reg (uint32_t fetchdat) \ - { \ - reg = POP_L(); \ - CLOCK_CYCLES((is486) ? 1 : 4); \ - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); \ - return cpu_state.abrt; \ - } +#define POP_L_OP(reg) \ + static int opPOP_##reg(uint32_t fetchdat) \ + { \ + reg = POP_L(); \ + CLOCK_CYCLES((is486) ? 1 : 4); \ + PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); \ + return cpu_state.abrt; \ + } PUSH_W_OP(AX) PUSH_W_OP(BX) @@ -70,100 +70,125 @@ POP_L_OP(EDI) POP_L_OP(EBP) POP_L_OP(ESP) - -static int opPUSHA_w(uint32_t fetchdat) +static int +opPUSHA_w(uint32_t fetchdat) { - if (stack32) - { - writememw(ss, ESP - 2, AX); - writememw(ss, ESP - 4, CX); - writememw(ss, ESP - 6, DX); - writememw(ss, ESP - 8, BX); - writememw(ss, ESP - 10, SP); - writememw(ss, ESP - 12, BP); - writememw(ss, ESP - 14, SI); - writememw(ss, ESP - 16, DI); - if (!cpu_state.abrt) ESP -= 16; - } - else - { - writememw(ss, ((SP - 2) & 0xFFFF), AX); - writememw(ss, ((SP - 4) & 0xFFFF), CX); - writememw(ss, ((SP - 6) & 0xFFFF), DX); - writememw(ss, ((SP - 8) & 0xFFFF), BX); - writememw(ss, ((SP - 10) & 0xFFFF), SP); - writememw(ss, ((SP - 12) & 0xFFFF), BP); - writememw(ss, ((SP - 14) & 0xFFFF), SI); - writememw(ss, ((SP - 16) & 0xFFFF), DI); - if (!cpu_state.abrt) SP -= 16; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,8,0, 0); - return cpu_state.abrt; + if (stack32) { + writememw(ss, ESP - 2, AX); + writememw(ss, ESP - 4, CX); + writememw(ss, ESP - 6, DX); + writememw(ss, ESP - 8, BX); + writememw(ss, ESP - 10, SP); + writememw(ss, ESP - 12, BP); + writememw(ss, ESP - 14, SI); + writememw(ss, ESP - 16, DI); + if (!cpu_state.abrt) + ESP -= 16; + } else { + writememw(ss, ((SP - 2) & 0xFFFF), AX); + writememw(ss, ((SP - 4) & 0xFFFF), CX); + writememw(ss, ((SP - 6) & 0xFFFF), DX); + writememw(ss, ((SP - 8) & 0xFFFF), BX); + writememw(ss, ((SP - 10) & 0xFFFF), SP); + writememw(ss, ((SP - 12) & 0xFFFF), BP); + writememw(ss, ((SP - 14) & 0xFFFF), SI); + writememw(ss, ((SP - 16) & 0xFFFF), DI); + if (!cpu_state.abrt) + SP -= 16; + } + CLOCK_CYCLES((is486) ? 11 : 18); + PREFETCH_RUN(18, 1, -1, 0, 0, 8, 0, 0); + return cpu_state.abrt; } -static int opPUSHA_l(uint32_t fetchdat) +static int +opPUSHA_l(uint32_t fetchdat) { - if (stack32) - { - writememl(ss, ESP - 4, EAX); - writememl(ss, ESP - 8, ECX); - writememl(ss, ESP - 12, EDX); - writememl(ss, ESP - 16, EBX); - writememl(ss, ESP - 20, ESP); - writememl(ss, ESP - 24, EBP); - writememl(ss, ESP - 28, ESI); - writememl(ss, ESP - 32, EDI); - if (!cpu_state.abrt) ESP -= 32; - } - else - { - writememl(ss, ((SP - 4) & 0xFFFF), EAX); - writememl(ss, ((SP - 8) & 0xFFFF), ECX); - writememl(ss, ((SP - 12) & 0xFFFF), EDX); - writememl(ss, ((SP - 16) & 0xFFFF), EBX); - writememl(ss, ((SP - 20) & 0xFFFF), ESP); - writememl(ss, ((SP - 24) & 0xFFFF), EBP); - writememl(ss, ((SP - 28) & 0xFFFF), ESI); - writememl(ss, ((SP - 32) & 0xFFFF), EDI); - if (!cpu_state.abrt) SP -= 32; - } - CLOCK_CYCLES((is486) ? 11 : 18); - PREFETCH_RUN(18, 1, -1, 0,0,0,8, 0); - return cpu_state.abrt; + if (stack32) { + writememl(ss, ESP - 4, EAX); + writememl(ss, ESP - 8, ECX); + writememl(ss, ESP - 12, EDX); + writememl(ss, ESP - 16, EBX); + writememl(ss, ESP - 20, ESP); + writememl(ss, ESP - 24, EBP); + writememl(ss, ESP - 28, ESI); + writememl(ss, ESP - 32, EDI); + if (!cpu_state.abrt) + ESP -= 32; + } else { + writememl(ss, ((SP - 4) & 0xFFFF), EAX); + writememl(ss, ((SP - 8) & 0xFFFF), ECX); + writememl(ss, ((SP - 12) & 0xFFFF), EDX); + writememl(ss, ((SP - 16) & 0xFFFF), EBX); + writememl(ss, ((SP - 20) & 0xFFFF), ESP); + writememl(ss, ((SP - 24) & 0xFFFF), EBP); + writememl(ss, ((SP - 28) & 0xFFFF), ESI); + writememl(ss, ((SP - 32) & 0xFFFF), EDI); + if (!cpu_state.abrt) + SP -= 32; + } + CLOCK_CYCLES((is486) ? 11 : 18); + PREFETCH_RUN(18, 1, -1, 0, 0, 0, 8, 0); + return cpu_state.abrt; } -static int opPOPA_w(uint32_t fetchdat) +static int +opPOPA_w(uint32_t fetchdat) { - if (stack32) - { - DI = readmemw(ss, ESP); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ESP + 2); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ESP + 4); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ESP + 8); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ESP + 10); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ESP + 12); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ESP + 14); if (cpu_state.abrt) return 1; - ESP += 16; - } - else - { - DI = readmemw(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - SI = readmemw(ss, ((SP + 2) & 0xFFFF)); if (cpu_state.abrt) return 1; - BP = readmemw(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - BX = readmemw(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - DX = readmemw(ss, ((SP + 10) & 0xFFFF)); if (cpu_state.abrt) return 1; - CX = readmemw(ss, ((SP + 12) & 0xFFFF)); if (cpu_state.abrt) return 1; - AX = readmemw(ss, ((SP + 14) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 16; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 7,0,0,0, 0); - return 0; + if (stack32) { + DI = readmemw(ss, ESP); + if (cpu_state.abrt) + return 1; + SI = readmemw(ss, ESP + 2); + if (cpu_state.abrt) + return 1; + BP = readmemw(ss, ESP + 4); + if (cpu_state.abrt) + return 1; + BX = readmemw(ss, ESP + 8); + if (cpu_state.abrt) + return 1; + DX = readmemw(ss, ESP + 10); + if (cpu_state.abrt) + return 1; + CX = readmemw(ss, ESP + 12); + if (cpu_state.abrt) + return 1; + AX = readmemw(ss, ESP + 14); + if (cpu_state.abrt) + return 1; + ESP += 16; + } else { + DI = readmemw(ss, ((SP) &0xFFFF)); + if (cpu_state.abrt) + return 1; + SI = readmemw(ss, ((SP + 2) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + BP = readmemw(ss, ((SP + 4) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + BX = readmemw(ss, ((SP + 8) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + DX = readmemw(ss, ((SP + 10) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + CX = readmemw(ss, ((SP + 12) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + AX = readmemw(ss, ((SP + 14) & 0xFFFF)); + if (cpu_state.abrt) + return 1; + SP += 16; + } + CLOCK_CYCLES((is486) ? 9 : 24); + PREFETCH_RUN(24, 1, -1, 7, 0, 0, 0, 0); + return 0; } -static int opPOPA_l(uint32_t fetchdat) +static int +opPOPA_l(uint32_t fetchdat) { - if (stack32) - { + if (stack32) { EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; @@ -172,9 +197,7 @@ static int opPOPA_l(uint32_t fetchdat) ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; ESP += 32; - } - else - { + } else { EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; @@ -189,302 +212,389 @@ static int opPOPA_l(uint32_t fetchdat) return 0; } -static int opPUSH_imm_w(uint32_t fetchdat) +static int +opPUSH_imm_w(uint32_t fetchdat) { - uint16_t val = getwordf(); - PUSH_W(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,1,0, 0); - return cpu_state.abrt; + uint16_t val = getwordf(); + PUSH_W(val); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 3, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; } -static int opPUSH_imm_l(uint32_t fetchdat) +static int +opPUSH_imm_l(uint32_t fetchdat) { - uint32_t val = getlong(); if (cpu_state.abrt) return 1; - PUSH_L(val); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 3, -1, 0,0,0,1, 0); - return cpu_state.abrt; + uint32_t val = getlong(); + if (cpu_state.abrt) + return 1; + PUSH_L(val); + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 3, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; } -static int opPUSH_imm_bw(uint32_t fetchdat) +static int +opPUSH_imm_bw(uint32_t fetchdat) { - uint16_t tempw = getbytef(); + uint16_t tempw = getbytef(); - if (tempw & 0x80) tempw |= 0xFF00; - PUSH_W(tempw); + if (tempw & 0x80) + tempw |= 0xFF00; + PUSH_W(tempw); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,1,0, 0); - return cpu_state.abrt; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, -1, 0, 0, 1, 0, 0); + return cpu_state.abrt; } -static int opPUSH_imm_bl(uint32_t fetchdat) +static int +opPUSH_imm_bl(uint32_t fetchdat) { - uint32_t templ = getbytef(); + uint32_t templ = getbytef(); - if (templ & 0x80) templ |= 0xFFFFFF00; - PUSH_L(templ); + if (templ & 0x80) + templ |= 0xFFFFFF00; + PUSH_L(templ); - CLOCK_CYCLES(2); - PREFETCH_RUN(2, 2, -1, 0,0,0,1, 0); - return cpu_state.abrt; + CLOCK_CYCLES(2); + PREFETCH_RUN(2, 2, -1, 0, 0, 0, 1, 0); + return cpu_state.abrt; } -static int opPOPW_a16(uint32_t fetchdat) +static int +opPOPW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - temp = POP_W(); if (cpu_state.abrt) return 1; + temp = POP_W(); + if (cpu_state.abrt) + return 1; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 2; + else + SP -= 2; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 0); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return cpu_state.abrt; } -static int opPOPW_a32(uint32_t fetchdat) +static int +opPOPW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - temp = POP_W(); if (cpu_state.abrt) return 1; + temp = POP_W(); + if (cpu_state.abrt) + return 1; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 2; - else SP -= 2; - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 2; + else + SP -= 2; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1,0,(cpu_mod == 3) ? 0:1,0, 1); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return cpu_state.abrt; } -static int opPOPL_a16(uint32_t fetchdat) +static int +opPOPL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - temp = POP_L(); if (cpu_state.abrt) return 1; + temp = POP_L(); + if (cpu_state.abrt) + return 1; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 4; + else + SP -= 4; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 0); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return cpu_state.abrt; } -static int opPOPL_a32(uint32_t fetchdat) +static int +opPOPL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - temp = POP_L(); if (cpu_state.abrt) return 1; + temp = POP_L(); + if (cpu_state.abrt) + return 1; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(temp); - if (cpu_state.abrt) - { - if (stack32) ESP -= 4; - else SP -= 4; - } + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(temp); + if (cpu_state.abrt) { + if (stack32) + ESP -= 4; + else + SP -= 4; + } - if (is486) { CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); } - else { CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); } - PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0,1,0,(cpu_mod == 3) ? 0:1, 1); - return cpu_state.abrt; + if (is486) { + CLOCK_CYCLES((cpu_mod == 3) ? 1 : 6); + } else { + CLOCK_CYCLES((cpu_mod == 3) ? 4 : 5); + } + PREFETCH_RUN((cpu_mod == 3) ? 4 : 5, 2, rmdat, 0, 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return cpu_state.abrt; } - -static int opENTER_w(uint32_t fetchdat) +static int +opENTER_w(uint32_t fetchdat) { - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0, writes = 1, instr_cycles = 0; #endif - uint16_t tempw; + uint16_t tempw; - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; - tempESP = ESP; + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; - PUSH_W(BP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; + PUSH_W(BP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; - if (count > 0) - { - while (--count) - { - BP -= 2; - tempw = readmemw(ss, BP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_W(tempw); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); + if (count > 0) { + while (--count) { + BP -= 2; + tempw = readmemw(ss, BP); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + PUSH_W(tempw); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 4); #ifndef IS_DYNAREC - reads++; writes++; instr_cycles += (is486) ? 3 : 4; -#endif - } - PUSH_W(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); -#ifndef IS_DYNAREC - writes++; instr_cycles += (is486) ? 3 : 5; + reads++; + writes++; + instr_cycles += (is486) ? 3 : 4; #endif } - BP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); + PUSH_W(frame_ptr); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 5); #ifndef IS_DYNAREC - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); + writes++; + instr_cycles += (is486) ? 3 : 5; #endif - return 0; + } + BP = frame_ptr; + + if (stack32) + ESP -= offset; + else + SP -= offset; + CLOCK_CYCLES((is486) ? 14 : 10); +#ifndef IS_DYNAREC + instr_cycles += (is486) ? 14 : 10; + PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0); +#endif + return 0; } -static int opENTER_l(uint32_t fetchdat) +static int +opENTER_l(uint32_t fetchdat) { - uint16_t offset; - int count; - uint32_t tempEBP, tempESP, frame_ptr; + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; #ifndef IS_DYNAREC - int reads = 0, writes = 1, instr_cycles = 0; + int reads = 0, writes = 1, instr_cycles = 0; #endif - uint32_t templ; + uint32_t templ; - offset = getwordf(); - count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - tempEBP = EBP; tempESP = ESP; + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; + cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; - PUSH_L(EBP); if (cpu_state.abrt) return 1; - frame_ptr = ESP; + PUSH_L(EBP); + if (cpu_state.abrt) + return 1; + frame_ptr = ESP; - if (count > 0) - { - while (--count) - { - EBP -= 4; - templ = readmeml(ss, EBP); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - PUSH_L(templ); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 4); + if (count > 0) { + while (--count) { + EBP -= 4; + templ = readmeml(ss, EBP); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + PUSH_L(templ); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 4); #ifndef IS_DYNAREC - reads++; writes++; instr_cycles += (is486) ? 3 : 4; -#endif - } - PUSH_L(frame_ptr); - if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } - CLOCK_CYCLES((is486) ? 3 : 5); -#ifndef IS_DYNAREC - writes++; instr_cycles += (is486) ? 3 : 5; + reads++; + writes++; + instr_cycles += (is486) ? 3 : 4; #endif } - EBP = frame_ptr; - - if (stack32) ESP -= offset; - else SP -= offset; - CLOCK_CYCLES((is486) ? 14 : 10); + PUSH_L(frame_ptr); + if (cpu_state.abrt) { + ESP = tempESP; + EBP = tempEBP; + return 1; + } + CLOCK_CYCLES((is486) ? 3 : 5); #ifndef IS_DYNAREC - instr_cycles += (is486) ? 14 : 10; - PREFETCH_RUN(instr_cycles, 3, -1, reads,0,writes,0, 0); + writes++; + instr_cycles += (is486) ? 3 : 5; #endif - return 0; + } + EBP = frame_ptr; + + if (stack32) + ESP -= offset; + else + SP -= offset; + CLOCK_CYCLES((is486) ? 14 : 10); +#ifndef IS_DYNAREC + instr_cycles += (is486) ? 14 : 10; + PREFETCH_RUN(instr_cycles, 3, -1, reads, 0, writes, 0, 0); +#endif + return 0; } - -static int opLEAVE_w(uint32_t fetchdat) +static int +opLEAVE_w(uint32_t fetchdat) { - uint32_t tempESP = ESP; - uint16_t temp; + uint32_t tempESP = ESP; + uint16_t temp; - SP = BP; - temp = POP_W(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - BP = temp; + SP = BP; + temp = POP_W(); + if (cpu_state.abrt) { + ESP = tempESP; + return 1; + } + BP = temp; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 1,0,0,0, 0); - return 0; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLEAVE_l(uint32_t fetchdat) +static int +opLEAVE_l(uint32_t fetchdat) { - uint32_t tempESP = ESP; - uint32_t temp; + uint32_t tempESP = ESP; + uint32_t temp; - ESP = EBP; - temp = POP_L(); - if (cpu_state.abrt) { ESP = tempESP; return 1; } - EBP = temp; + ESP = EBP; + temp = POP_L(); + if (cpu_state.abrt) { + ESP = tempESP; + return 1; + } + EBP = temp; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,1,0,0, 0); - return 0; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 1, 0, 0, 0); + return 0; } +#define PUSH_SEG_OPS(seg) \ + static int opPUSH_##seg##_w(uint32_t fetchdat) \ + { \ + PUSH_W(seg); \ + CLOCK_CYCLES(2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } \ + static int opPUSH_##seg##_l(uint32_t fetchdat) \ + { \ + PUSH_L(seg); \ + CLOCK_CYCLES(2); \ + PREFETCH_RUN(2, 1, -1, 0, 0, 0, 1, 0); \ + return cpu_state.abrt; \ + } -#define PUSH_SEG_OPS(seg) \ - static int opPUSH_ ## seg ## _w(uint32_t fetchdat) \ - { \ - PUSH_W(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPUSH_ ## seg ## _l(uint32_t fetchdat) \ - { \ - PUSH_L(seg); \ - CLOCK_CYCLES(2); \ - PREFETCH_RUN(2, 1, -1, 0,0,0,1, 0); \ - return cpu_state.abrt; \ - } - -#define POP_SEG_OPS(seg, realseg) \ - static int opPOP_ ## seg ## _w(uint32_t fetchdat) \ - { \ - uint16_t temp_seg; \ - uint32_t temp_esp = ESP; \ - temp_seg = POP_W(); if (cpu_state.abrt) return 1; \ - loadseg(temp_seg, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } \ - static int opPOP_ ## seg ## _l(uint32_t fetchdat) \ - { \ - uint32_t temp_seg; \ - uint32_t temp_esp = ESP; \ - temp_seg = POP_L(); if (cpu_state.abrt) return 1; \ - loadseg(temp_seg & 0xffff, realseg); if (cpu_state.abrt) ESP = temp_esp; \ - CLOCK_CYCLES(is486 ? 3 : 7); \ - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); \ - return cpu_state.abrt; \ - } - +#define POP_SEG_OPS(seg, realseg) \ + static int opPOP_##seg##_w(uint32_t fetchdat) \ + { \ + uint16_t temp_seg; \ + uint32_t temp_esp = ESP; \ + temp_seg = POP_W(); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(temp_seg, realseg); \ + if (cpu_state.abrt) \ + ESP = temp_esp; \ + CLOCK_CYCLES(is486 ? 3 : 7); \ + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } \ + static int opPOP_##seg##_l(uint32_t fetchdat) \ + { \ + uint32_t temp_seg; \ + uint32_t temp_esp = ESP; \ + temp_seg = POP_L(); \ + if (cpu_state.abrt) \ + return 1; \ + loadseg(temp_seg & 0xffff, realseg); \ + if (cpu_state.abrt) \ + ESP = temp_esp; \ + CLOCK_CYCLES(is486 ? 3 : 7); \ + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); \ + return cpu_state.abrt; \ + } PUSH_SEG_OPS(CS) PUSH_SEG_OPS(DS) @@ -497,44 +607,59 @@ POP_SEG_OPS(ES, &cpu_state.seg_es) POP_SEG_OPS(FS, &cpu_state.seg_fs) POP_SEG_OPS(GS, &cpu_state.seg_gs) - -static int opPOP_SS_w(uint32_t fetchdat) +static int +opPOP_SS_w(uint32_t fetchdat) { - uint16_t temp_seg; - uint32_t temp_esp = ESP; - temp_seg = POP_W(); if (cpu_state.abrt) return 1; - loadseg(temp_seg, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - + uint16_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_W(); + if (cpu_state.abrt) return 1; + loadseg(temp_seg, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + CLOCK_CYCLES(is486 ? 3 : 7); + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + + return 1; } -static int opPOP_SS_l(uint32_t fetchdat) +static int +opPOP_SS_l(uint32_t fetchdat) { - uint32_t temp_seg; - uint32_t temp_esp = ESP; - temp_seg = POP_L(); if (cpu_state.abrt) return 1; - loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); if (cpu_state.abrt) { ESP = temp_esp; return 1; } - CLOCK_CYCLES(is486 ? 3 : 7); - PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0,0,1,0, 0); - - cpu_state.oldpc = cpu_state.pc; - cpu_state.op32 = use32; - cpu_state.ssegs = 0; - cpu_state.ea_seg = &cpu_state.seg_ds; - fetchdat = fastreadl(cs + cpu_state.pc); - cpu_state.pc++; - if (cpu_state.abrt) return 1; - x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); - + uint32_t temp_seg; + uint32_t temp_esp = ESP; + temp_seg = POP_L(); + if (cpu_state.abrt) return 1; + loadseg(temp_seg & 0xffff, &cpu_state.seg_ss); + if (cpu_state.abrt) { + ESP = temp_esp; + return 1; + } + CLOCK_CYCLES(is486 ? 3 : 7); + PREFETCH_RUN(is486 ? 3 : 7, 1, -1, 0, 0, 1, 0, 0); + + cpu_state.oldpc = cpu_state.pc; + cpu_state.op32 = use32; + cpu_state.ssegs = 0; + cpu_state.ea_seg = &cpu_state.seg_ds; + fetchdat = fastreadl(cs + cpu_state.pc); + cpu_state.pc++; + if (cpu_state.abrt) + return 1; + x86_opcodes[(fetchdat & 0xff) | cpu_state.op32](fetchdat >> 8); + + return 1; } diff --git a/src/cpu/x86_ops_string.h b/src/cpu/x86_ops_string.h index 54a22d4b8..5cc5f3806 100644 --- a/src/cpu/x86_ops_string.h +++ b/src/cpu/x86_ops_string.h @@ -1,792 +1,1095 @@ -static int opMOVSB_a16(uint32_t fetchdat) +static int +opMOVSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - high_page = 0; - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); - do_mmut_wb(es, DI, &addr64_2); - if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; - writememb_n(es, DI, addr64_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; + do_mmut_wb(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, DI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opMOVSB_a32(uint32_t fetchdat) +static int +opMOVSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - high_page = 0; - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - do_mmut_wb(es, EDI, &addr64_2); - if (cpu_state.abrt) return 1; - temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; - writememb_n(es, EDI, addr64_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + high_page = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + temp = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + writememb_n(es, EDI, addr64_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opMOVSW_a16(uint32_t fetchdat) +static int +opMOVSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - high_page = 0; - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - do_mmut_ww(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - writememw_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + do_mmut_ww(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opMOVSW_a32(uint32_t fetchdat) +static int +opMOVSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - high_page = 0; - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_ww(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - writememw_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + high_page = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememw_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opMOVSL_a16(uint32_t fetchdat) +static int +opMOVSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - high_page = 0; - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - do_mmut_wl(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - writememl_n(es, DI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + do_mmut_wl(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, DI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opMOVSL_a32(uint32_t fetchdat) +static int +opMOVSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - high_page = 0; - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - do_mmut_wl(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - writememl_n(es, EDI, addr64a_2, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + high_page = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + do_mmut_wl(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + temp = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + writememl_n(es, EDI, addr64a_2, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 1, 1); + return 0; } - -static int opCMPSB_a16(uint32_t fetchdat) +static int +opCMPSB_a16(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - high_page = uncached = 0; - do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI); - do_mmut_rb2(es, DI, &addr64_2); - if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmemb_n(es, DI, addr64_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub8(src, dst); - if (cpu_state.flags & D_FLAG) { DI--; SI--; } - else { DI++; SI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, SI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + do_mmut_rb2(es, DI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, SI, addr64); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmemb_n(es, DI, addr64_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + DI--; + SI--; + } else { + DI++; + SI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; } -static int opCMPSB_a32(uint32_t fetchdat) +static int +opCMPSB_a32(uint32_t fetchdat) { - uint8_t src, dst; + uint8_t src, dst; - addr64 = addr64_2 = 0x00000000; + addr64 = addr64_2 = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - high_page = uncached = 0; - do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI); - do_mmut_rb2(es, EDI, &addr64_2); - if (cpu_state.abrt) return 1; - src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmemb_n(es, EDI, addr64_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub8(src, dst); - if (cpu_state.flags & D_FLAG) { EDI--; ESI--; } - else { EDI++; ESI++; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + high_page = uncached = 0; + do_mmut_rb(cpu_state.ea_seg->base, ESI, &addr64); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + do_mmut_rb2(es, EDI, &addr64_2); + if (cpu_state.abrt) + return 1; + src = readmemb_n(cpu_state.ea_seg->base, ESI, addr64); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmemb_n(es, EDI, addr64_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub8(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI--; + ESI--; + } else { + EDI++; + ESI++; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; } -static int opCMPSW_a16(uint32_t fetchdat) +static int +opCMPSW_a16(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - high_page = uncached = 0; - do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); - do_mmut_rw2(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmemw_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { DI -= 2; SI -= 2; } - else { DI += 2; SI += 2; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + do_mmut_rw2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmemw_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 2; + SI -= 2; + } else { + DI += 2; + SI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 0); + return 0; } -static int opCMPSW_a32(uint32_t fetchdat) +static int +opCMPSW_a32(uint32_t fetchdat) { - uint16_t src, dst; + uint16_t src, dst; - addr64a[0] = addr64a[1] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - high_page = uncached = 0; - do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_rw2(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmemw_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub16(src, dst); - if (cpu_state.flags & D_FLAG) { EDI -= 2; ESI -= 2; } - else { EDI += 2; ESI += 2; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + high_page = uncached = 0; + do_mmut_rw(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_rw2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmemw_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmemw_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub16(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 2; + ESI -= 2; + } else { + EDI += 2; + ESI += 2; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 2, 0, 0, 0, 1); + return 0; } -static int opCMPSL_a16(uint32_t fetchdat) +static int +opCMPSL_a16(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - high_page = uncached = 0; - do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); - do_mmut_rl2(es, DI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = old_rl2; - dst = readmeml_n(es, DI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+DI)>>12] = (uintptr_t) LOOKUP_INV; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { DI -= 4; SI -= 4; } - else { DI += 4; SI += 4; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + do_mmut_rl2(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, SI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = old_rl2; + dst = readmeml_n(es, DI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + DI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + DI -= 4; + SI -= 4; + } else { + DI += 4; + SI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 0); + return 0; } -static int opCMPSL_a32(uint32_t fetchdat) +static int +opCMPSL_a32(uint32_t fetchdat) { - uint32_t src, dst; + uint32_t src, dst; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a_2[0] = addr64a_2[1] = addr64a_2[2] = addr64a_2[3] = 0x00000000; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - high_page = uncached = 0; - do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); - if (cpu_state.abrt) return 1; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); - do_mmut_rl2(es, EDI, addr64a_2); - if (cpu_state.abrt) return 1; - src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = old_rl2; - dst = readmeml_n(es, EDI, addr64a_2); if (cpu_state.abrt) return 1; - if (uncached) - readlookup2[(uint32_t)(es+EDI)>>12] = (uintptr_t) LOOKUP_INV; - setsub32(src, dst); - if (cpu_state.flags & D_FLAG) { EDI -= 4; ESI -= 4; } - else { EDI += 4; ESI += 4; } - CLOCK_CYCLES((is486) ? 8 : 10); - PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0,2,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + high_page = uncached = 0; + do_mmut_rl(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + do_mmut_rl2(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + src = readmeml_n(cpu_state.ea_seg->base, ESI, addr64a); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = old_rl2; + dst = readmeml_n(es, EDI, addr64a_2); + if (cpu_state.abrt) + return 1; + if (uncached) + readlookup2[(uint32_t) (es + EDI) >> 12] = (uintptr_t) LOOKUP_INV; + setsub32(src, dst); + if (cpu_state.flags & D_FLAG) { + EDI -= 4; + ESI -= 4; + } else { + EDI += 4; + ESI += 4; + } + CLOCK_CYCLES((is486) ? 8 : 10); + PREFETCH_RUN((is486) ? 8 : 10, 1, -1, 0, 2, 0, 0, 1); + return 0; } -static int opSTOSB_a16(uint32_t fetchdat) +static int +opSTOSB_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); - writememb(es, DI, AL); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + writememb(es, DI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } -static int opSTOSB_a32(uint32_t fetchdat) +static int +opSTOSB_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - writememb(es, EDI, AL); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + writememb(es, EDI, AL); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } -static int opSTOSW_a16(uint32_t fetchdat) +static int +opSTOSW_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - writememw(es, DI, AX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + writememw(es, DI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 0); + return 0; } -static int opSTOSW_a32(uint32_t fetchdat) +static int +opSTOSW_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - writememw(es, EDI, AX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + writememw(es, EDI, AX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 1, 0, 1); + return 0; } -static int opSTOSL_a16(uint32_t fetchdat) +static int +opSTOSL_a16(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - writememl(es, DI, EAX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + writememl(es, DI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 0); + return 0; } -static int opSTOSL_a32(uint32_t fetchdat) +static int +opSTOSL_a32(uint32_t fetchdat) { - SEG_CHECK_WRITE(&cpu_state.seg_es); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - writememl(es, EDI, EAX); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(4); - PREFETCH_RUN(4, 1, -1, 0,0,0,1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + writememl(es, EDI, EAX); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(4); + PREFETCH_RUN(4, 1, -1, 0, 0, 0, 1, 1); + return 0; } - -static int opLODSB_a16(uint32_t fetchdat) +static int +opLODSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) SI--; - else SI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLODSB_a32(uint32_t fetchdat) +static int +opLODSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AL = temp; - if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AL = temp; + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opLODSW_a16(uint32_t fetchdat) +static int +opLODSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opLODSW_a32(uint32_t fetchdat) +static int +opLODSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - AX = temp; - if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + AX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opLODSL_a16(uint32_t fetchdat) +static int +opLODSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 0); + return 0; } -static int opLODSL_a32(uint32_t fetchdat) +static int +opLODSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - EAX = temp; - if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; - CLOCK_CYCLES(5); - PREFETCH_RUN(5, 1, -1, 0,1,0,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + EAX = temp; + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + CLOCK_CYCLES(5); + PREFETCH_RUN(5, 1, -1, 0, 1, 0, 0, 1); + return 0; } - -static int opSCASB_a16(uint32_t fetchdat) +static int +opSCASB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI); - temp = readmemb(es, DI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI); + temp = readmemb(es, DI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opSCASB_a32(uint32_t fetchdat) +static int +opSCASB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI); - temp = readmemb(es, EDI); if (cpu_state.abrt) return 1; - setsub8(AL, temp); - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI); + temp = readmemb(es, EDI); + if (cpu_state.abrt) + return 1; + setsub8(AL, temp); + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opSCASW_a16(uint32_t fetchdat) +static int +opSCASW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); - temp = readmemw(es, DI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 1UL); + temp = readmemw(es, DI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 0); + return 0; } -static int opSCASW_a32(uint32_t fetchdat) +static int +opSCASW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); - temp = readmemw(es, EDI); if (cpu_state.abrt) return 1; - setsub16(AX, temp); - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 1,0,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 1UL); + temp = readmemw(es, EDI); + if (cpu_state.abrt) + return 1; + setsub16(AX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 1, 0, 0, 0, 1); + return 0; } -static int opSCASL_a16(uint32_t fetchdat) +static int +opSCASL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); - temp = readmeml(es, DI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 0); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, DI, DI + 3UL); + temp = readmeml(es, DI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 0); + return 0; } -static int opSCASL_a32(uint32_t fetchdat) +static int +opSCASL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(&cpu_state.seg_es); - CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); - temp = readmeml(es, EDI); if (cpu_state.abrt) return 1; - setsub32(EAX, temp); - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(7); - PREFETCH_RUN(7, 1, -1, 0,1,0,0, 1); - return 0; + SEG_CHECK_READ(&cpu_state.seg_es); + CHECK_READ(&cpu_state.seg_es, EDI, EDI + 3UL); + temp = readmeml(es, EDI); + if (cpu_state.abrt) + return 1; + setsub32(EAX, temp); + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(7); + PREFETCH_RUN(7, 1, -1, 0, 1, 0, 0, 1); + return 0; } -static int opINSB_a16(uint32_t fetchdat) +static int +opINSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = 0x00000000; + addr64 = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - CHECK_WRITE(&cpu_state.seg_es, DI, DI); - high_page = 0; - do_mmut_wb(es, DI, &addr64); if (cpu_state.abrt) return 1; - temp = inb(DX); - writememb_n(es, DI, addr64, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI--; - else DI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + CHECK_WRITE(&cpu_state.seg_es, DI, DI); + high_page = 0; + do_mmut_wb(es, DI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, DI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI--; + else + DI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opINSB_a32(uint32_t fetchdat) +static int +opINSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - addr64 = 0x00000000; + addr64 = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - high_page = 0; - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); - do_mmut_wb(es, EDI, &addr64); if (cpu_state.abrt) return 1; - temp = inb(DX); - writememb_n(es, EDI, addr64, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI--; - else EDI++; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + high_page = 0; + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI); + do_mmut_wb(es, EDI, &addr64); + if (cpu_state.abrt) + return 1; + temp = inb(DX); + writememb_n(es, EDI, addr64, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI--; + else + EDI++; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opINSW_a16(uint32_t fetchdat) +static int +opINSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); - high_page = 0; - do_mmut_ww(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inw(DX); - writememw_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 2; - else DI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL); + high_page = 0; + do_mmut_ww(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 2; + else + DI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opINSW_a32(uint32_t fetchdat) +static int +opINSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - addr64a[0] = addr64a[1] = 0x00000000; + addr64a[0] = addr64a[1] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - high_page = 0; - check_io_perm(DX); - check_io_perm(DX + 1); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); - do_mmut_ww(es, EDI, addr64a); if (cpu_state.abrt) return 1; - temp = inw(DX); - writememw_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 2; - else EDI += 2; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + high_page = 0; + check_io_perm(DX); + check_io_perm(DX + 1); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL); + do_mmut_ww(es, EDI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inw(DX); + writememw_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 2; + else + EDI += 2; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opINSL_a16(uint32_t fetchdat) +static int +opINSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); - high_page = 0; - do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inl(DX); - writememl_n(es, DI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) DI -= 4; - else DI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, DI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + DI -= 4; + else + DI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opINSL_a32(uint32_t fetchdat) +static int +opINSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; + addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000; - SEG_CHECK_WRITE(&cpu_state.seg_es); - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); - high_page = 0; - do_mmut_wl(es, DI, addr64a); if (cpu_state.abrt) return 1; - temp = inl(DX); - writememl_n(es, EDI, addr64a, temp); if (cpu_state.abrt) return 1; - if (cpu_state.flags & D_FLAG) EDI -= 4; - else EDI += 4; - CLOCK_CYCLES(15); - PREFETCH_RUN(15, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_WRITE(&cpu_state.seg_es); + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL); + high_page = 0; + do_mmut_wl(es, DI, addr64a); + if (cpu_state.abrt) + return 1; + temp = inl(DX); + writememl_n(es, EDI, addr64a, temp); + if (cpu_state.abrt) + return 1; + if (cpu_state.flags & D_FLAG) + EDI -= 4; + else + EDI += 4; + CLOCK_CYCLES(15); + PREFETCH_RUN(15, 1, -1, 0, 1, 0, 1, 1); + return 0; } -static int opOUTSB_a16(uint32_t fetchdat) +static int +opOUTSB_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI); - temp = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) SI--; - else SI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI); + temp = readmemb(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + SI--; + else + SI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opOUTSB_a32(uint32_t fetchdat) +static int +opOUTSB_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI); - temp = readmemb(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - if (cpu_state.flags & D_FLAG) ESI--; - else ESI++; - outb(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI); + temp = readmemb(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + if (cpu_state.flags & D_FLAG) + ESI--; + else + ESI++; + outb(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opOUTSW_a16(uint32_t fetchdat) +static int +opOUTSW_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.flags & D_FLAG) SI -= 2; - else SI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.flags & D_FLAG) + SI -= 2; + else + SI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 0); + return 0; } -static int opOUTSW_a32(uint32_t fetchdat) +static int +opOUTSW_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); - temp = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - if (cpu_state.flags & D_FLAG) ESI -= 2; - else ESI += 2; - outw(DX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 1,0,1,0, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 1UL); + temp = readmemw(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + if (cpu_state.flags & D_FLAG) + ESI -= 2; + else + ESI += 2; + outw(DX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 1, 0, 1, 0, 1); + return 0; } -static int opOUTSL_a16(uint32_t fetchdat) +static int +opOUTSL_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (cpu_state.flags & D_FLAG) SI -= 4; - else SI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 0); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, SI, SI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, SI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + if (cpu_state.flags & D_FLAG) + SI -= 4; + else + SI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 0); + return 0; } -static int opOUTSL_a32(uint32_t fetchdat) +static int +opOUTSL_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - SEG_CHECK_READ(cpu_state.ea_seg); - CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); - temp = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) return 1; - check_io_perm(DX); - check_io_perm(DX + 1); - check_io_perm(DX + 2); - check_io_perm(DX + 3); - if (cpu_state.flags & D_FLAG) ESI -= 4; - else ESI += 4; - outl(EDX, temp); - CLOCK_CYCLES(14); - PREFETCH_RUN(14, 1, -1, 0,1,0,1, 1); - return 0; + SEG_CHECK_READ(cpu_state.ea_seg); + CHECK_READ(cpu_state.ea_seg, ESI, ESI + 3UL); + temp = readmeml(cpu_state.ea_seg->base, ESI); + if (cpu_state.abrt) + return 1; + check_io_perm(DX); + check_io_perm(DX + 1); + check_io_perm(DX + 2); + check_io_perm(DX + 3); + if (cpu_state.flags & D_FLAG) + ESI -= 4; + else + ESI += 4; + outl(EDX, temp); + CLOCK_CYCLES(14); + PREFETCH_RUN(14, 1, -1, 0, 1, 0, 1, 1); + return 0; } diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index 300e97f25..c572608eb 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -1,228 +1,270 @@ -static int opXCHG_b_a16(uint32_t fetchdat) +static int +opXCHG_b_a16(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opXCHG_b_a32(uint32_t fetchdat) +static int +opXCHG_b_a32(uint32_t fetchdat) { - uint8_t temp; + uint8_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteab(); if (cpu_state.abrt) return 1; - seteab(getr8(cpu_reg)); if (cpu_state.abrt) return 1; - setr8(cpu_reg, temp); - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteab(); + if (cpu_state.abrt) + return 1; + seteab(getr8(cpu_reg)); + if (cpu_state.abrt) + return 1; + setr8(cpu_reg, temp); + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } -static int opXCHG_w_a16(uint32_t fetchdat) +static int +opXCHG_w_a16(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 0); + return 0; } -static int opXCHG_w_a32(uint32_t fetchdat) +static int +opXCHG_w_a32(uint32_t fetchdat) { - uint16_t temp; + uint16_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - seteaw(cpu_state.regs[cpu_reg].w); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].w = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1,0, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + seteaw(cpu_state.regs[cpu_reg].w); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].w = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0, 1); + return 0; } -static int opXCHG_l_a16(uint32_t fetchdat) +static int +opXCHG_l_a16(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_16(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); - return 0; + fetch_ea_16(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 0); + return 0; } -static int opXCHG_l_a32(uint32_t fetchdat) +static int +opXCHG_l_a32(uint32_t fetchdat) { - uint32_t temp; + uint32_t temp; - fetch_ea_32(fetchdat); - if (cpu_mod != 3) - SEG_CHECK_WRITE(cpu_state.ea_seg); - temp = geteal(); if (cpu_state.abrt) return 1; - seteal(cpu_state.regs[cpu_reg].l); if (cpu_state.abrt) return 1; - cpu_state.regs[cpu_reg].l = temp; - CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); - PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); - return 0; + fetch_ea_32(fetchdat); + if (cpu_mod != 3) + SEG_CHECK_WRITE(cpu_state.ea_seg); + temp = geteal(); + if (cpu_state.abrt) + return 1; + seteal(cpu_state.regs[cpu_reg].l); + if (cpu_state.abrt) + return 1; + cpu_state.regs[cpu_reg].l = temp; + CLOCK_CYCLES((cpu_mod == 3) ? 3 : 5); + PREFETCH_RUN((cpu_mod == 3) ? 3 : 5, 2, rmdat, 0, (cpu_mod == 3) ? 0 : 1, 0, (cpu_mod == 3) ? 0 : 1, 1); + return 0; } - -static int opXCHG_AX_BX(uint32_t fetchdat) +static int +opXCHG_AX_BX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = BX; - BX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = BX; + BX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_CX(uint32_t fetchdat) +static int +opXCHG_AX_CX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = CX; - CX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = CX; + CX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_DX(uint32_t fetchdat) +static int +opXCHG_AX_DX(uint32_t fetchdat) { - uint16_t temp = AX; - AX = DX; - DX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = DX; + DX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_SI(uint32_t fetchdat) +static int +opXCHG_AX_SI(uint32_t fetchdat) { - uint16_t temp = AX; - AX = SI; - SI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = SI; + SI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_DI(uint32_t fetchdat) +static int +opXCHG_AX_DI(uint32_t fetchdat) { - uint16_t temp = AX; - AX = DI; - DI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = DI; + DI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_BP(uint32_t fetchdat) +static int +opXCHG_AX_BP(uint32_t fetchdat) { - uint16_t temp = AX; - AX = BP; - BP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = BP; + BP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_AX_SP(uint32_t fetchdat) +static int +opXCHG_AX_SP(uint32_t fetchdat) { - uint16_t temp = AX; - AX = SP; - SP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint16_t temp = AX; + AX = SP; + SP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EBX(uint32_t fetchdat) +static int +opXCHG_EAX_EBX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EBX; - EBX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EBX; + EBX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ECX(uint32_t fetchdat) +static int +opXCHG_EAX_ECX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ECX; - ECX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ECX; + ECX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EDX(uint32_t fetchdat) +static int +opXCHG_EAX_EDX(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EDX; - EDX = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EDX; + EDX = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ESI(uint32_t fetchdat) +static int +opXCHG_EAX_ESI(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ESI; - ESI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ESI; + ESI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EDI(uint32_t fetchdat) +static int +opXCHG_EAX_EDI(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EDI; - EDI = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EDI; + EDI = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_EBP(uint32_t fetchdat) +static int +opXCHG_EAX_EBP(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = EBP; - EBP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = EBP; + EBP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } -static int opXCHG_EAX_ESP(uint32_t fetchdat) +static int +opXCHG_EAX_ESP(uint32_t fetchdat) { - uint32_t temp = EAX; - EAX = ESP; - ESP = temp; - CLOCK_CYCLES(3); - PREFETCH_RUN(3, 1, -1, 0,0,0,0, 0); - return 0; + uint32_t temp = EAX; + EAX = ESP; + ESP = temp; + CLOCK_CYCLES(3); + PREFETCH_RUN(3, 1, -1, 0, 0, 0, 0, 0); + return 0; } - -#define opBSWAP(reg) \ - static int opBSWAP_ ## reg(uint32_t fetchdat) \ - { \ - reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ - CLOCK_CYCLES(1); \ - PREFETCH_RUN(1, 1, -1, 0,0,0,0, 0); \ - return 0; \ - } +#define opBSWAP(reg) \ + static int opBSWAP_##reg(uint32_t fetchdat) \ + { \ + reg = (reg >> 24) | ((reg >> 8) & 0xff00) | ((reg << 8) & 0xff0000) | ((reg << 24) & 0xff000000); \ + CLOCK_CYCLES(1); \ + PREFETCH_RUN(1, 1, -1, 0, 0, 0, 0, 0); \ + return 0; \ + } opBSWAP(EAX) opBSWAP(EBX) diff --git a/src/cpu/x86seg.c b/src/cpu/x86seg.c index 74539c067..c1e9e5b3d 100644 --- a/src/cpu/x86seg.c +++ b/src/cpu/x86seg.c @@ -35,7 +35,6 @@ #include "x86_flags.h" #include "386_common.h" - uint8_t opcode2; int cgate16, cgate32; @@ -45,54 +44,50 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32); void pmodeint(int num, int soft); -#define DPL ((segdat[2] >> 13) & 3) +#define DPL ((segdat[2] >> 13) & 3) #define DPL2 ((segdat2[2] >> 13) & 3) #define DPL3 ((segdat3[2] >> 13) & 3) - #ifdef ENABLE_X86SEG_LOG int x86seg_do_log = ENABLE_X86SEG_LOG; - static void x86seg_log(const char *fmt, ...) { va_list ap; if (x86seg_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define x86seg_log(fmt, ...) +# define x86seg_log(fmt, ...) #endif - static void seg_reset(x86seg *s) { - s->access = 0x82; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; + s->access = 0x82; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; s->limit_high = 0xffff; if (s == &cpu_state.seg_cs) { - if (!cpu_inited) - fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); - if (is6117) - s->base = 0x03ff0000; - else - s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; - s->seg = is286 ? 0xf000 : 0xffff; + if (!cpu_inited) + fatal("seg_reset(&cpu_state.seg.cs) without an initialized CPU\n"); + if (is6117) + s->base = 0x03ff0000; + else + s->base = is286 ? (cpu_16bitbus ? 0x00ff0000 : 0xffff0000) : 0x000ffff0; + s->seg = is286 ? 0xf000 : 0xffff; } else { - s->base = 0; - s->seg = 0; + s->base = 0; + s->seg = 0; } } - void x86seg_reset(void) { @@ -104,239 +99,234 @@ x86seg_reset(void) seg_reset(&cpu_state.seg_ss); } - void x86_doabrt(int x86_abrt) { #ifndef USE_NEW_DYNAREC CS = oldcs; #endif - cpu_state.pc = cpu_state.oldpc; - cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; + cpu_state.pc = cpu_state.oldpc; + cpu_state.seg_cs.access = (oldcpl << 5) | 0x80; cpu_state.seg_cs.ar_high = 0x10; if (msw & 1) - pmodeint(x86_abrt, 0); + pmodeint(x86_abrt, 0); else { - uint32_t addr = (x86_abrt << 2) + idt.base; - if (stack32) { - writememw(ss, ESP - 2, cpu_state.flags); - writememw(ss, ESP - 4, CS); - writememw(ss, ESP - 6, cpu_state.pc); - ESP -= 6; - } else { - writememw(ss, ((SP - 2) & 0xffff), cpu_state.flags); - writememw(ss, ((SP - 4) & 0xffff), CS); - writememw(ss, ((SP - 6) & 0xffff), cpu_state.pc); - SP -= 6; - } + uint32_t addr = (x86_abrt << 2) + idt.base; + if (stack32) { + writememw(ss, ESP - 2, cpu_state.flags); + writememw(ss, ESP - 4, CS); + writememw(ss, ESP - 6, cpu_state.pc); + ESP -= 6; + } else { + writememw(ss, ((SP - 2) & 0xffff), cpu_state.flags); + writememw(ss, ((SP - 4) & 0xffff), CS); + writememw(ss, ((SP - 6) & 0xffff), cpu_state.pc); + SP -= 6; + } - cpu_state.flags &= ~(I_FLAG | T_FLAG); + cpu_state.flags &= ~(I_FLAG | T_FLAG); #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - cpu_state.pc = readmemw(0, addr); - loadcs(readmemw(0, addr + 2)); - return; + cpu_state.pc = readmemw(0, addr); + loadcs(readmemw(0, addr + 2)); + return; } if (cpu_state.abrt || x86_was_reset) - return; + return; if (intgatesize == 16) { - if (stack32) { - writememw(ss, ESP - 2, abrt_error); - ESP -= 2; - } else { - writememw(ss, ((SP - 2) & 0xffff), abrt_error); - SP -= 2; - } + if (stack32) { + writememw(ss, ESP - 2, abrt_error); + ESP -= 2; + } else { + writememw(ss, ((SP - 2) & 0xffff), abrt_error); + SP -= 2; + } } else { - if (stack32) { - writememl(ss, ESP - 4, abrt_error); - ESP -= 4; - } else { - writememl(ss, ((SP - 4) & 0xffff), abrt_error); - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, abrt_error); + ESP -= 4; + } else { + writememl(ss, ((SP - 4) & 0xffff), abrt_error); + SP -= 4; + } } } - void x86de(char *s, uint16_t error) { #ifdef BAD_CODE cpu_state.abrt = ABRT_DE; - abrt_error = error; + abrt_error = error; #else x86_int(0); #endif } - void x86gpf(char *s, uint16_t error) { cpu_state.abrt = ABRT_GPF; - abrt_error = error; + abrt_error = error; } - void x86gpf_expected(char *s, uint16_t error) { cpu_state.abrt = ABRT_GPF | ABRT_EXPECTED; - abrt_error = error; + abrt_error = error; } - void x86ss(char *s, uint16_t error) { cpu_state.abrt = ABRT_SS; - abrt_error = error; + abrt_error = error; } - -void x86ts(char *s, uint16_t error) +void +x86ts(char *s, uint16_t error) { cpu_state.abrt = ABRT_TS; - abrt_error = error; + abrt_error = error; } - void x86np(char *s, uint16_t error) { cpu_state.abrt = ABRT_NP; - abrt_error = error; + abrt_error = error; } - static void set_stack32(int s) { stack32 = s; if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; + cpu_cur_status |= CPU_STATUS_STACK32; else - cpu_cur_status &= ~CPU_STATUS_STACK32; + cpu_cur_status &= ~CPU_STATUS_STACK32; } - static void set_use32(int u) { use32 = u ? 0x300 : 0; if (u) - cpu_cur_status |= CPU_STATUS_USE32; + cpu_cur_status |= CPU_STATUS_USE32; else - cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_cur_status &= ~CPU_STATUS_USE32; } - void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0x000f) << 16); if (segdat[3] & 0x0080) - s->limit = (s->limit << 12) | 0xfff; + s->limit = (s->limit << 12) | 0xfff; s->base = segdat[1] | ((segdat[2] & 0x00ff) << 16); if (is386) - s->base |= ((segdat[3] >> 8) << 24); - s->access = segdat[2] >> 8; + s->base |= ((segdat[3] >> 8) << 24); + s->access = segdat[2] >> 8; s->ar_high = segdat[3] & 0xff; if (((segdat[2] & 0x1800) != 0x1000) || !(segdat[2] & (1 << 10))) { - /* Expand-down */ - s->limit_high = s->limit; - s->limit_low = 0; + /* Expand-down */ + s->limit_high = s->limit; + s->limit_low = 0; } else { - s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; - s->limit_low = s->limit + 1; + s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; + s->limit_low = s->limit + 1; } if (s == &cpu_state.seg_ds) { - if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + if ((s->base == 0) && (s->limit_low == 0) && (s->limit_high == 0xffffffff)) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } } - static void do_seg_v86_init(x86seg *s) { - s->access = 0xe2; - s->ar_high = 0x10; - s->limit = 0xffff; - s->limit_low = 0; + s->access = 0xe2; + s->ar_high = 0x10; + s->limit = 0xffff; + s->limit_low = 0; s->limit_high = 0xffff; } - static void check_seg_valid(x86seg *s) { - int dpl = (s->access >> 5) & 3; - int valid = 1; - x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; + int dpl = (s->access >> 5) & 3; + int valid = 1; + x86seg *dt = (s->seg & 0x0004) ? &ldt : &gdt; if (((s->seg & 0xfff8UL) + 7UL) > dt->limit) - valid = 0; + valid = 0; switch (s->access & 0x1f) { - case 0x10: case 0x11: case 0x12: case 0x13: /* Data segments */ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1a: case 0x1b: /* Readable non-conforming code */ - if (((s->seg & 3) > dpl) || ((CPL) > dpl)) { - valid = 0; - break; - } - break; + case 0x10: + case 0x11: + case 0x12: + case 0x13: /* Data segments */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1a: + case 0x1b: /* Readable non-conforming code */ + if (((s->seg & 3) > dpl) || ((CPL) > dpl)) { + valid = 0; + break; + } + break; - case 0x1e: case 0x1f: /* Readable conforming code */ - break; + case 0x1e: + case 0x1f: /* Readable conforming code */ + break; - default: - valid = 0; - break; + default: + valid = 0; + break; } if (!valid) - loadseg(0, s); + loadseg(0, s); } - static void read_descriptor(uint32_t addr, uint16_t *segdat, uint32_t *segdat32, int override) { if (override) - cpl_override = 1; + cpl_override = 1; if (cpu_16bitbus) { - segdat[0] = readmemw(0, addr); - segdat[1] = readmemw(0, addr + 2); - segdat[2] = readmemw(0, addr + 4); - segdat[3] = readmemw(0, addr + 6); + segdat[0] = readmemw(0, addr); + segdat[1] = readmemw(0, addr + 2); + segdat[2] = readmemw(0, addr + 4); + segdat[3] = readmemw(0, addr + 6); } else { - segdat32[0] = readmeml(0, addr); - segdat32[1] = readmeml(0, addr + 4); + segdat32[0] = readmeml(0, addr); + segdat32[1] = readmeml(0, addr + 4); } if (override) - cpl_override = 0; + cpl_override = 0; } - #ifdef USE_NEW_DYNAREC int #else @@ -346,180 +336,191 @@ loadseg(uint16_t seg, x86seg *s) { uint16_t segdat[4]; uint32_t addr, *segdat32 = (uint32_t *) segdat; - int dpl; - x86seg *dt; + int dpl; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - if (s == &cpu_state.seg_ss) { - x86ss(NULL,0); + if (!(seg & 0xfffc)) { + if (s == &cpu_state.seg_ss) { + x86ss(NULL, 0); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - s->seg = 0; - s->access = 0x80; - s->ar_high = 0x10; - s->base = -1; - if (s == &cpu_state.seg_ds) - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + } + s->seg = 0; + s->access = 0x80; + s->ar_high = 0x10; + s->base = -1; + if (s == &cpu_state.seg_ds) + cpu_cur_status |= CPU_STATUS_NOTFLATDS; #ifdef USE_NEW_DYNAREC - return 0; + return 0; #else - return; + return; #endif - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadseg(): Bigger than LDT limit", seg & 0xfffc); + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadseg(): Bigger than LDT limit", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - dpl = (segdat[2] >> 13) & 3; - if (s == &cpu_state.seg_ss) { - if (!(seg & 0xfffc)) { - x86gpf("loadseg(): Zero stack segment", seg & 0xfffc); + dpl = (segdat[2] >> 13) & 3; + if (s == &cpu_state.seg_ss) { + if (!(seg & 0xfffc)) { + x86gpf("loadseg(): Zero stack segment", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if ((seg & 0x0003) != CPL) { - x86gpf("loadseg(): Stack segment RPL != CPL", seg & 0xfffc); + } + if ((seg & 0x0003) != CPL) { + x86gpf("loadseg(): Stack segment RPL != CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if (dpl != CPL) { - x86gpf("loadseg(): Stack segment DPL != CPL", seg & 0xfffc); + } + if (dpl != CPL) { + x86gpf("loadseg(): Stack segment DPL != CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - switch ((segdat[2] >> 8) & 0x1f) { - case 0x12: case 0x13: case 0x16: case 0x17: - /* R/W */ - break; - default: - x86gpf("loadseg(): Unknown stack segment type", seg & ~3); + } + switch ((segdat[2] >> 8) & 0x1f) { + case 0x12: + case 0x13: + case 0x16: + case 0x17: + /* R/W */ + break; + default: + x86gpf("loadseg(): Unknown stack segment type", seg & ~3); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if (!(segdat[2] & 0x8000)) { - x86ss(NULL, seg & 0xfffc); + } + if (!(segdat[2] & 0x8000)) { + x86ss(NULL, seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - set_stack32((segdat[3] & 0x40) ? 1 : 0); - } else if (s != &cpu_state.seg_cs) { - x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - x86seg_log("Seg type %03X\n",segdat[2] & 0x1f00); - switch ((segdat[2] >> 8) & 0x1f) { - case 0x10: case 0x11: case 0x12: case 0x13: /* Data segments */ - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x1a: case 0x1b: /* Readable non-conforming code */ - if ((seg & 0x0003) > dpl) { - x86gpf("loadseg(): Normal segment RPL > DPL", seg & 0xfffc); + } + set_stack32((segdat[3] & 0x40) ? 1 : 0); + } else if (s != &cpu_state.seg_cs) { + x86seg_log("Seg data %04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + x86seg_log("Seg type %03X\n", segdat[2] & 0x1f00); + switch ((segdat[2] >> 8) & 0x1f) { + case 0x10: + case 0x11: + case 0x12: + case 0x13: /* Data segments */ + case 0x14: + case 0x15: + case 0x16: + case 0x17: + case 0x1a: + case 0x1b: /* Readable non-conforming code */ + if ((seg & 0x0003) > dpl) { + x86gpf("loadseg(): Normal segment RPL > DPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - if ((CPL) > dpl) { - x86gpf("loadseg(): Normal segment DPL < CPL", seg& 0xfffc); + } + if ((CPL) > dpl) { + x86gpf("loadseg(): Normal segment DPL < CPL", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - break; - case 0x1e: case 0x1f: /* Readable conforming code */ - break; - default: - x86gpf("loadseg(): Unknown normal segment type", seg & 0xfffc); + } + break; + case 0x1e: + case 0x1f: /* Readable conforming code */ + break; + default: + x86gpf("loadseg(): Unknown normal segment type", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - } + } + } - if (!(segdat[2] & 0x8000)) { - x86np("Load data seg not present", seg & 0xfffc); + if (!(segdat[2] & 0x8000)) { + x86np("Load data seg not present", seg & 0xfffc); #ifdef USE_NEW_DYNAREC - return 1; + return 1; #else - return; + return; #endif - } - s->seg = seg; - do_seg_load(s, segdat); + } + s->seg = seg; + do_seg_load(s, segdat); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - s->checked = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + s->checked = 0; #ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; #endif } else { - s->access = 0xe2; - s->ar_high = 0x10; - s->base = seg << 4; - s->seg = seg; - s->checked = 1; + s->access = 0xe2; + s->ar_high = 0x10; + s->base = seg << 4; + s->seg = seg; + s->checked = 1; #ifdef USE_DYNAREC - if (s == &cpu_state.seg_ds) - codegen_flat_ds = 0; - if (s == &cpu_state.seg_ss) - codegen_flat_ss = 0; + if (s == &cpu_state.seg_ds) + codegen_flat_ds = 0; + if (s == &cpu_state.seg_ss) + codegen_flat_ss = 0; #endif - if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) - set_stack32(0); + if (s == &cpu_state.seg_ss && (cpu_state.eflags & VM_FLAG)) + set_stack32(0); } if (s == &cpu_state.seg_ds) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; } if (s == &cpu_state.seg_ss) { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; } #ifdef USE_NEW_DYNAREC @@ -527,1884 +528,1922 @@ loadseg(uint16_t seg, x86seg *s) #endif } - void loadcs(uint16_t seg) { uint16_t segdat[4]; uint32_t addr, *segdat32 = (uint32_t *) segdat; - x86seg *dt; + x86seg *dt; x86seg_log("Load CS %04X\n", seg); if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - x86gpf("loadcs(): Protected mode selector is zero", 0); - return; - } + if (!(seg & 0xfffc)) { + x86gpf("loadcs(): Protected mode selector is zero", 0); + return; + } - addr = seg & 0xfff8; - dt = (seg & 0x0004)? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcs(): Protected mode selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - if (segdat[2] & 0x1000) { - /* Normal code segment */ - if (!(segdat[2] & 0x0400)) { - /* Not conforming */ - if ((seg & 3) > CPL) { - x86gpf("loadcs(): Non-conforming RPL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcs(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcs(): CPL < DPL", seg & ~3); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x40); - CS = (seg & 0xfffc) | CPL; - do_seg_load(&cpu_state.seg_cs, segdat); - use32 = (segdat[3] & 0x40) ? 0x300 : 0; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + if (segdat[2] & 0x1000) { + /* Normal code segment */ + if (!(segdat[2] & 0x0400)) { + /* Not conforming */ + if ((seg & 3) > CPL) { + x86gpf("loadcs(): Non-conforming RPL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcs(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcs(): CPL < DPL", seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x40); + CS = (seg & 0xfffc) | CPL; + do_seg_load(&cpu_state.seg_cs, segdat); + use32 = (segdat[3] & 0x40) ? 0x300 : 0; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ - cpl_override = 0; - } else { - /* System segment */ - if (!(segdat[2] & 0x8000)) { - x86np("Load CS system seg not present", seg & 0xfffc); - return; - } - switch (segdat[2] & 0x0f00) { - default: - x86gpf("Load CS system segment has bits 0-3 of access rights set", seg & 0xfffc); - return; - } - } + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ + cpl_override = 0; + } else { + /* System segment */ + if (!(segdat[2] & 0x8000)) { + x86np("Load CS system seg not present", seg & 0xfffc); + return; + } + switch (segdat[2] & 0x0f00) { + default: + x86gpf("Load CS system segment has bits 0-3 of access rights set", seg & 0xfffc); + return; + } + } } else { - cpu_state.seg_cs.base = (seg << 4); - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg & 0xffff; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = (seg << 4); + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg & 0xffff; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif } } - void loadcsjmp(uint16_t seg, uint32_t old_pc) { - uint16_t type, seg2; - uint16_t segdat[4]; - uint32_t addr, newpc; + uint16_t type, seg2; + uint16_t segdat[4]; + uint32_t addr, newpc; uint32_t *segdat32 = (uint32_t *) segdat; - x86seg *dt; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - if (!(seg & 0xfffc)) { - x86gpf("loadcsjmp(): Selector is zero", 0); - return; - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - x86seg_log("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); - if (segdat[2] & 0x1000) { - /* Normal code segment */ - if (!(segdat[2] & 0x0400)) { - /* Not conforming */ - if ((seg & 0x0003) > CPL) { - x86gpf("loadcsjmp(): segment PL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcsjmp(): CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcsjmp(): CPL < DPL",seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x0040); + if (!(seg & 0xfffc)) { + x86gpf("loadcsjmp(): Selector is zero", 0); + return; + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loacsjmp(): Selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + x86seg_log("%04X %04X %04X %04X\n", segdat[0], segdat[1], segdat[2], segdat[3]); + if (segdat[2] & 0x1000) { + /* Normal code segment */ + if (!(segdat[2] & 0x0400)) { + /* Not conforming */ + if ((seg & 0x0003) > CPL) { + x86gpf("loadcsjmp(): segment PL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcsjmp(): CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcsjmp(): CPL < DPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x0100); /* Set accessed bit */ + cpl_override = 0; - CS = (seg & 0xfffc) | CPL; - segdat[2] = (segdat[2] & ~(3 << 13)) | (CPL << 13); + CS = (seg & 0xfffc) | CPL; + segdat[2] = (segdat[2] & ~(3 << 13)) | (CPL << 13); - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cycles -= timing_jmp_pm; - } else { /* System segment */ - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP system selector not present", seg & 0xfffc); - return; - } - type = segdat[2] & 0x0f00; - newpc = segdat[0]; - if (type & 0x0800) - newpc |= (segdat[3] << 16); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_jmp_pm; + } else { /* System segment */ + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP system selector not present", seg & 0xfffc); + return; + } + type = segdat[2] & 0x0f00; + newpc = segdat[0]; + if (type & 0x0800) + newpc |= (segdat[3] << 16); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs=CS; + oldcs = CS; #endif - cpu_state.oldpc = cpu_state.pc; - if (DPL < CPL) { - x86gpf("loadcsjmp(): Call gate DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcsjmp(): Call gate DPL< RPL",seg&~3); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + cpu_state.oldpc = cpu_state.pc; + if (DPL < CPL) { + x86gpf("loadcsjmp(): Call gate DPL < CPL", seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcsjmp(): Call gate DPL< RPL", seg & ~3); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - if (!(seg2 & 0xfffc)) { - x86gpf("Load CS JMP call gate selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("Load CS JMP call gate selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcsjmp(): Call gate selector > DT limit", seg2 & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; - if (DPL > CPL) { - x86gpf("loadcsjmp(): ex DPL > CPL",seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS JMP from call gate not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcsjmp(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS JMP from call gate not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL > CPL) { - x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if (DPL > CPL) { + x86gpf("loadcsjmp(): Non-conforming DPL > CPL", seg2 & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; + set_use32(segdat[3] & 0x40); + cpu_state.pc = newpc; - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - break; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + break; - default: - x86gpf("loadcsjmp(): Unknown type", seg2 & 0xfffc); - return; - } - cycles -= timing_jmp_pm_gate; - break; + default: + x86gpf("loadcsjmp(): Unknown type", seg2 & 0xfffc); + return; + } + cycles -= timing_jmp_pm_gate; + break; - case 0x100: /* 286 Task gate */ - case 0x900: /* 386 Task gate */ - cpu_state.pc = old_pc; - optype = JMP; - cpl_override = 1; - taskswitch286(seg,segdat,segdat[2] & 0x800); - cpu_state.flags &= ~NT_FLAG; - cpl_override=0; - return; + case 0x100: /* 286 Task gate */ + case 0x900: /* 386 Task gate */ + cpu_state.pc = old_pc; + optype = JMP; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x800); + cpu_state.flags &= ~NT_FLAG; + cpl_override = 0; + return; - default: - x86gpf("Load CS JMP call gate selector unknown type", 0); - return; - } - } + default: + x86gpf("Load CS JMP call gate selector unknown type", 0); + return; + } + } } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - cycles -= timing_jmp_rm; + cycles -= timing_jmp_rm; } } - void PUSHW(uint16_t v) { if (stack32) { - writememw(ss, ESP - 2, v); - if (cpu_state.abrt) - return; - ESP -= 2; + writememw(ss, ESP - 2, v); + if (cpu_state.abrt) + return; + ESP -= 2; } else { - writememw(ss, ((SP - 2) & 0xffff), v); - if (cpu_state.abrt) - return; - SP -= 2; + writememw(ss, ((SP - 2) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 2; } } - void PUSHL(uint32_t v) { if (cpu_16bitbus) { - PUSHW(v >> 16); - PUSHW(v & 0xffff); + PUSHW(v >> 16); + PUSHW(v & 0xffff); } else { - if (stack32) { - writememl(ss, ESP - 4, v); - if (cpu_state.abrt) - return; - ESP -= 4; - } else { - writememl(ss, ((SP - 4) & 0xffff), v); - if (cpu_state.abrt) - return; - SP -= 4; - } + if (stack32) { + writememl(ss, ESP - 4, v); + if (cpu_state.abrt) + return; + ESP -= 4; + } else { + writememl(ss, ((SP - 4) & 0xffff), v); + if (cpu_state.abrt) + return; + SP -= 4; + } } } - uint16_t POPW(void) { uint16_t tempw; if (stack32) { - tempw = readmemw(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 2; + tempw = readmemw(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 2; } else { - tempw = readmemw(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 2; + tempw = readmemw(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 2; } return tempw; } - uint32_t POPL(void) { uint32_t templ; if (cpu_16bitbus) { - templ = POPW(); - templ |= (POPW() << 16); + templ = POPW(); + templ |= (POPW() << 16); } else { - if (stack32) { - templ = readmeml(ss, ESP); - if (cpu_state.abrt) - return 0; - ESP += 4; - } else { - templ = readmeml(ss, SP); - if (cpu_state.abrt) - return 0; - SP += 4; - } + if (stack32) { + templ = readmeml(ss, ESP); + if (cpu_state.abrt) + return 0; + ESP += 4; + } else { + templ = readmeml(ss, SP); + if (cpu_state.abrt) + return 0; + SP += 4; + } } return templ; } - #ifdef USE_NEW_DYNAREC -void loadcscall(uint16_t seg, uint32_t old_pc) +void +loadcscall(uint16_t seg, uint32_t old_pc) #else -void loadcscall(uint16_t seg) +void +loadcscall(uint16_t seg) #endif { - uint16_t seg2, newss; - uint16_t segdat[4], segdat2[4]; - uint32_t addr, oldssbase = ss; - uint32_t oaddr, newpc; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t seg2, newss; + uint16_t segdat[4], segdat2[4]; + uint32_t addr, oldssbase = ss; + uint32_t oaddr, newpc; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - int count, type; - uint32_t oldss, oldsp, newsp, oldsp2; - uint16_t tempw; - x86seg *dt; + int count, type; + uint32_t oldss, oldsp, newsp, oldsp2; + uint16_t tempw; + x86seg *dt; if ((msw & 1) && !(cpu_state.eflags & VM_FLAG)) { - x86seg_log("Protected mode CS load! %04X\n", seg); - if (!(seg & 0xfffc)) { - x86gpf("loadcscall(): Protected mode selector is zero",0); - return; - } - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; - type = segdat[2] & 0x0f00; - newpc = segdat[0]; - if (type & 0x0800) - newpc |= segdat[3] << 16; + x86seg_log("Protected mode CS load! %04X\n", seg); + if (!(seg & 0xfffc)) { + x86gpf("loadcscall(): Protected mode selector is zero", 0); + return; + } + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): Selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; + type = segdat[2] & 0x0f00; + newpc = segdat[0]; + if (type & 0x0800) + newpc |= segdat[3] << 16; - x86seg_log("Code seg call - %04X - %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2]); - if (segdat[2] & 0x1000) { - if (!(segdat[2] & 0x0400)) { /* Not conforming */ - if ((seg & 0x0003) > CPL) { - x86gpf("loadcscall(): Non-conforming RPL > CPL", seg & 0xfffc); - return; - } - if (CPL != DPL) { - x86gpf("loadcscall(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - } - if (CPL < DPL) { - x86gpf("loadcscall(): CPL < DPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Load CS call not present", seg & 0xfffc); - return; - } - set_use32(segdat[3] & 0x0040); + x86seg_log("Code seg call - %04X - %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2]); + if (segdat[2] & 0x1000) { + if (!(segdat[2] & 0x0400)) { /* Not conforming */ + if ((seg & 0x0003) > CPL) { + x86gpf("loadcscall(): Non-conforming RPL > CPL", seg & 0xfffc); + return; + } + if (CPL != DPL) { + x86gpf("loadcscall(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + } + if (CPL < DPL) { + x86gpf("loadcscall(): CPL < DPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Load CS call not present", seg & 0xfffc); + return; + } + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - /* Conforming segments don't change CPL, so preserve existing CPL */ - if (segdat[2] & 0x0400) { - seg = (seg & 0xfffc) | CPL; - segdat[2] = (segdat[2] & ~(3 << (5+8))) | (CPL << (5+8)); - } else /* On non-conforming segments, set RPL = CPL */ - seg = (seg & 0xfffc) | CPL; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + /* Conforming segments don't change CPL, so preserve existing CPL */ + if (segdat[2] & 0x0400) { + seg = (seg & 0xfffc) | CPL; + segdat[2] = (segdat[2] & ~(3 << (5 + 8))) | (CPL << (5 + 8)); + } else /* On non-conforming segments, set RPL = CPL */ + seg = (seg & 0xfffc) | CPL; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif #ifdef ENABLE_X86SEG_LOG - x86seg_log("Complete\n"); + x86seg_log("Complete\n"); #endif - cycles -= timing_call_pm; - } else { - type = segdat[2] & 0x0f00; - x86seg_log("Type %03X\n", type); - switch (type) { - case 0x0400: /* Call gate */ - case 0x0c00: /* 386 Call gate */ - x86seg_log("Callgate %08X\n", cpu_state.pc); - cgate32 = (type & 0x0800); - cgate16 = !cgate32; + cycles -= timing_call_pm; + } else { + type = segdat[2] & 0x0f00; + x86seg_log("Type %03X\n", type); + switch (type) { + case 0x0400: /* Call gate */ + case 0x0c00: /* 386 Call gate */ + x86seg_log("Callgate %08X\n", cpu_state.pc); + cgate32 = (type & 0x0800); + cgate16 = !cgate32; #ifndef USE_NEW_DYNAREC - oldcs = CS; + oldcs = CS; #endif - count = segdat[2] & 0x001f; - if (DPL < CPL) { - x86gpf("loadcscall(): ex DPL < CPL",seg & 0xfffc); - return; - } - if (DPL < (seg & 0x0003)) { - x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86np("Call gate not present", seg & 0xfffc); - return; - } - seg2 = segdat[1]; + count = segdat[2] & 0x001f; + if (DPL < CPL) { + x86gpf("loadcscall(): ex DPL < CPL", seg & 0xfffc); + return; + } + if (DPL < (seg & 0x0003)) { + x86gpf("loadcscall(): ex DPL < RPL", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86np("Call gate not present", seg & 0xfffc); + return; + } + seg2 = segdat[1]; - x86seg_log("New address : %04X:%08X\n", seg2, newpc); + x86seg_log("New address : %04X:%08X\n", seg2, newpc); - if (!(seg2 & 0xfffc)) { - x86gpf("loadcscall(): ex selector is NULL", 0); - return; - } - addr = seg2 & 0xfff8; - dt = (seg2 & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); - return; - } - addr += dt->base; - read_descriptor(addr, segdat, segdat32, 1); - if (cpu_state.abrt) - return; + if (!(seg2 & 0xfffc)) { + x86gpf("loadcscall(): ex selector is NULL", 0); + return; + } + addr = seg2 & 0xfff8; + dt = (seg2 & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("loadcscall(): ex Selector > DT limit", seg2 & 0xfff8); + return; + } + addr += dt->base; + read_descriptor(addr, segdat, segdat32, 1); + if (cpu_state.abrt) + return; - x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); + x86seg_log("Code seg2 call - %04X - %04X %04X %04X\n", seg2, segdat[0], segdat[1], segdat[2]); - if (DPL > CPL) { - x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - x86seg_log("Call gate CS not present %04X\n", seg2); - x86np("Call gate CS not present", seg2 & 0xfffc); - return; - } + if (DPL > CPL) { + x86gpf("loadcscall(): ex DPL > CPL", seg2 & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + x86seg_log("Call gate CS not present %04X\n", seg2); + x86np("Call gate CS not present", seg2 & 0xfffc); + return; + } - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if (DPL < CPL) { + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if (DPL < CPL) { #ifdef USE_NEW_DYNAREC - uint16_t oldcs = CS; + uint16_t oldcs = CS; #endif - oaddr = addr; - /* Load new stack */ - oldss = SS; - oldsp = oldsp2 = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL << 3); - newss = readmemw(0, addr + 4); - if (cpu_16bitbus) { - newsp = readmemw(0, addr); - newsp |= (readmemw(0, addr + 2) << 16); - } else - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL * 4); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (cpu_state.abrt) - return; - x86seg_log("New stack %04X:%08X\n", newss, newsp); - if (!(newss & 0xfffc)) { - x86ts(NULL, newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); - x86ts(NULL, newss & ~3); - return; - } - addr += dt->base; - x86seg_log("Read stack seg\n"); - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - x86seg_log("Read stack seg done!\n"); - if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { - x86ts(NULL, newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - x86ts("Call gate loading SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - x86ss("Call gate loading SS not present", newss & 0xfffc); - return; - } - if (!stack32) - oldsp &= 0xffff; - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; + oaddr = addr; + /* Load new stack */ + oldss = SS; + oldsp = oldsp2 = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL << 3); + newss = readmemw(0, addr + 4); + if (cpu_16bitbus) { + newsp = readmemw(0, addr); + newsp |= (readmemw(0, addr + 2) << 16); + } else + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL * 4); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (cpu_state.abrt) + return; + x86seg_log("New stack %04X:%08X\n", newss, newsp); + if (!(newss & 0xfffc)) { + x86ts(NULL, newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + fatal("Bigger than DT limit %04X %08X %04X CSC SS\n", newss, addr, dt->limit); + x86ts(NULL, newss & ~3); + return; + } + addr += dt->base; + x86seg_log("Read stack seg\n"); + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + x86seg_log("Read stack seg done!\n"); + if (((newss & 0x0003) != DPL) || (DPL2 != DPL)) { + x86ts(NULL, newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + x86ts("Call gate loading SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + x86ss("Call gate loading SS not present", newss & 0xfffc); + return; + } + if (!stack32) + oldsp &= 0xffff; + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + do_seg_load(&cpu_state.seg_ss, segdat2); - x86seg_log("Set access 1\n"); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + x86seg_log("Set access 1\n"); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - x86seg_log("Set access 2\n"); + x86seg_log("Set access 2\n"); - cpl_override = 1; - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("Type %04X\n", type); - if (type == 0x0c00) { - PUSHL(oldss); - PUSHL(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + x86seg_log("Type %04X\n", type); + if (type == 0x0c00) { + PUSHL(oldss); + PUSHL(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - if (count) { - while (count--) { - PUSHL(readmeml(oldssbase, oldsp + (count << 2))); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + if (count) { + while (count--) { + PUSHL(readmeml(oldssbase, oldsp + (count << 2))); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - } - } - } else { - x86seg_log("Stack %04X\n", SP); - PUSHW(oldss); - x86seg_log("Write SS to %04X:%04X\n", SS, SP); - PUSHW(oldsp2); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + } + } + } else { + x86seg_log("Stack %04X\n", SP); + PUSHW(oldss); + x86seg_log("Write SS to %04X:%04X\n", SS, SP); + PUSHW(oldsp2); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - x86seg_log("Write SP to %04X:%04X\n", SS, SP); - if (count) { - while (count--) { - tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); - x86seg_log("PUSH %04X\n", tempw); - PUSHW(tempw); - if (cpu_state.abrt) { - SS = oldss; - ESP = oldsp2; + return; + } + x86seg_log("Write SP to %04X:%04X\n", SS, SP); + if (count) { + while (count--) { + tempw = readmemw(oldssbase, (oldsp & 0xffff) + (count << 1)); + x86seg_log("PUSH %04X\n", tempw); + PUSHW(tempw); + if (cpu_state.abrt) { + SS = oldss; + ESP = oldsp2; #ifdef USE_NEW_DYNAREC - CS = oldcs; + CS = oldcs; #endif - return; - } - } - } - } - cycles -= timing_call_pm_gate_inner; - break; - } else if (DPL > CPL) { - x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL",seg2 & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - CS = seg2; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + return; + } + } + } + } + cycles -= timing_call_pm_gate_inner; + break; + } else if (DPL > CPL) { + x86gpf("loadcscall(): Call PM Gate Inner DPL > CPL", seg2 & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + CS = seg2; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); - cpu_state.pc = newpc; + set_use32(segdat[3] & 0x0040); + cpu_state.pc = newpc; - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - cycles -= timing_call_pm_gate; - break; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + cycles -= timing_call_pm_gate; + break; - default: - x86gpf("loadcscall(): Unknown subtype", seg2 & 0xfffc); - return; - } - break; + default: + x86gpf("loadcscall(): Unknown subtype", seg2 & 0xfffc); + return; + } + break; - case 0x0100: /* 286 Task gate */ - case 0x0900: /* 386 Task gate */ + case 0x0100: /* 286 Task gate */ + case 0x0900: /* 386 Task gate */ #ifdef USE_NEW_DYNAREC - cpu_state.pc = old_pc; + cpu_state.pc = old_pc; #else - cpu_state.pc = oxpc; + cpu_state.pc = oxpc; #endif - cpl_override = 1; - taskswitch286(seg, segdat, segdat[2] & 0x0800); - cpl_override = 0; - break; + cpl_override = 1; + taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 0; + break; - default: - x86gpf("loadcscall(): Unknown type", seg & 0xfffc); - return; - } - } + default: + x86gpf("loadcscall(): Unknown type", seg & 0xfffc); + return; + } + } } else { - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.seg = seg; - cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.seg = seg; + cpu_state.seg_cs.access = (cpu_state.eflags & VM_FLAG) ? 0xe2 : 0x82; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif } } - void pmoderetf(int is32, uint16_t off) { - uint16_t segdat[4], segdat2[4], seg,newss; - uint32_t newpc, newsp, addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t segdat[4], segdat2[4], seg, newss; + uint32_t newpc, newsp, addr, oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; x86seg_log("RETF %i %04X:%04X %08X %04X\n", is32, CS, cpu_state.pc, cr0, cpu_state.eflags); if (is32) { - newpc = POPL(); - seg = POPL(); + newpc = POPL(); + seg = POPL(); } else { - x86seg_log("PC read from %04X:%04X\n", SS, SP); - newpc = POPW(); - x86seg_log("CS read from %04X:%04X\n", SS, SP); - seg = POPW(); + x86seg_log("PC read from %04X:%04X\n", SS, SP); + newpc = POPW(); + x86seg_log("CS read from %04X:%04X\n", SS, SP); + seg = POPW(); } if (cpu_state.abrt) - return; + return; x86seg_log("Return to %04X:%08X\n", seg, newpc); if ((seg & 0x0003) < CPL) { - ESP = oldsp; - x86gpf("pmoderetf(): seg < CPL", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmoderetf(): seg < CPL", seg & 0xfffc); + return; } if (!(seg & 0xfffc)) { - x86gpf("pmoderetf(): seg is NULL", 0); - return; + x86gpf("pmoderetf(): seg is NULL", 0); + return; } addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; + dt = (seg & 0x0004) ? &ldt : &gdt; if ((addr + 7) > dt->limit) { - x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); - return; + x86gpf("pmoderetf(): Selector > DT limit", seg & 0xfffc); + return; } addr += dt->base; read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - ESP = oldsp; - return; + ESP = oldsp; + return; } oaddr = addr; x86seg_log("CPL %i RPL %i %i\n", CPL, seg & 0x0003, is32); if (stack32) - ESP += off; + ESP += off; else - SP += off; + SP += off; if (CPL == (seg & 0x0003)) { - x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if (CPL != DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Non-conforming CPL != DPL", seg & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if (CPL < DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Conforming CPL < DPL", seg & 0xfffc); - return; - } - break; - default: - x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF CS not present", seg & 0xfffc); - return; - } + x86seg_log("RETF CPL = RPL %04X\n", segdat[2]); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if (CPL != DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Non-conforming CPL != DPL", seg & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if (CPL < DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Conforming CPL < DPL", seg & 0xfffc); + return; + } + break; + default: + x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF CS not present", seg & 0xfffc); + return; + } - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - cpu_state.pc = newpc; - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.pc = newpc; + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~(3 << 5)) | ((CS & 3) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - cycles -= timing_retf_pm; + cycles -= timing_retf_pm; } else { - switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((seg & 0x0003) != DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Non-conforming RPL != DPL", seg & 0xfffc); - return; - } - x86seg_log("RETF non-conforming, %i %i\n", seg & 0x0003, DPL); - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((seg & 0x0003) < DPL) { - ESP = oldsp; - x86gpf("pmoderetf(): Conforming RPL < DPL", seg & 0xfffc); - return; - } - x86seg_log("RETF conforming, %i %i\n", seg & 0x0003, DPL); - break; - default: - ESP = oldsp; - x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); - return; - } - if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF CS not present", seg & 0xfffc); - return; - } - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) - return; - } else { - x86seg_log("SP read from %04X:%04X\n", SS, SP); - newsp = POPW(); - x86seg_log("SS read from %04X:%04X\n", SS, SP); - newss = POPW(); - if (cpu_state.abrt) - return; - } - x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); - if (!(newss & 0xfffc)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS selector is zero",newss&~3); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); - if ((newss & 0x0003) != (seg & 0x0003)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS RPL > CS RPL", newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS unknown type", newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - ESP = oldsp; - x86np("RETF loading SS not present", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 3)) { - ESP = oldsp; - x86gpf("pmoderetf(): New SS DPL != CS RPL",newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat2[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + switch (segdat[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((seg & 0x0003) != DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Non-conforming RPL != DPL", seg & 0xfffc); + return; + } + x86seg_log("RETF non-conforming, %i %i\n", seg & 0x0003, DPL); + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((seg & 0x0003) < DPL) { + ESP = oldsp; + x86gpf("pmoderetf(): Conforming RPL < DPL", seg & 0xfffc); + return; + } + x86seg_log("RETF conforming, %i %i\n", seg & 0x0003, DPL); + break; + default: + ESP = oldsp; + x86gpf("pmoderetf(): Unknown type", seg & 0xfffc); + return; + } + if (!(segdat[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF CS not present", seg & 0xfffc); + return; + } + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) + return; + } else { + x86seg_log("SP read from %04X:%04X\n", SS, SP); + newsp = POPW(); + x86seg_log("SS read from %04X:%04X\n", SS, SP); + newss = POPW(); + if (cpu_state.abrt) + return; + } + x86seg_log("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); + if (!(newss & 0xfffc)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS selector is zero", newss & ~3); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS selector > DT limit", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + x86seg_log("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); + if ((newss & 0x0003) != (seg & 0x0003)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS RPL > CS RPL", newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS unknown type", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + ESP = oldsp; + x86np("RETF loading SS not present", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 3)) { + ESP = oldsp; + x86gpf("pmoderetf(): New SS DPL != CS RPL", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat2[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat2); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - /* Conforming segments don't change CPL, so CPL = RPL */ - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - cpu_state.pc = newpc; - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + /* Conforming segments don't change CPL, so CPL = RPL */ + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + cpu_state.pc = newpc; + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - if (stack32) - ESP += off; - else - SP += off; + if (stack32) + ESP += off; + else + SP += off; - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_retf_pm_outer; + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_retf_pm_outer; } } - void pmodeint(int num, int soft) { - uint16_t segdat[4], segdat2[4]; - uint16_t segdat3[4]; - uint16_t newss, seg = 0; - int type, new_cpl; - uint32_t addr, oaddr; - uint32_t oldss, oldsp; - uint32_t newsp; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t segdat[4], segdat2[4]; + uint16_t segdat3[4]; + uint16_t newss, seg = 0; + int type, new_cpl; + uint32_t addr, oaddr; + uint32_t oldss, oldsp; + uint32_t newsp; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; uint32_t *segdat332 = (uint32_t *) segdat3; - x86seg *dt; + x86seg *dt; if ((cpu_state.eflags & VM_FLAG) && (IOPL != 3) && soft) { - x86seg_log("V86 banned int\n"); - x86gpf("pmodeint(): V86 banned int", 0); - return; + x86seg_log("V86 banned int\n"); + x86gpf("pmodeint(): V86 banned int", 0); + return; } addr = (num << 3); if ((addr + 7) > idt.limit) { - if (num == 0x08) { - /* Triple fault - reset! */ - softresetx86(); - cpu_set_edx(); - } else if (num == 0x0d) - pmodeint(8, 0); - else - x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); - x86seg_log("addr >= IDT.limit\n"); - return; + if (num == 0x08) { + /* Triple fault - reset! */ + softresetx86(); + cpu_set_edx(); + } else if (num == 0x0d) + pmodeint(8, 0); + else + x86gpf("pmodeint(): Vector > IDT limit", (num << 3) + 2 + !soft); + x86seg_log("addr >= IDT.limit\n"); + return; } addr += idt.base; read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - x86seg_log("Abrt reading from %08X\n", addr); - return; + x86seg_log("Abrt reading from %08X\n", addr); + return; } oaddr = addr; x86seg_log("Addr %08X seg %04X %04X %04X %04X\n", addr, segdat[0], segdat[1], segdat[2], segdat[3]); if (!(segdat[2] & 0x1f00)) { - /* This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn */ - if (cpu_state.eflags & VM_FLAG) - x86gpf_expected("pmodeint(): Expected vector descriptor with bad type", (num << 3) + 2); - else - x86gpf("pmodeint(): Vector descriptor with bad type", (num << 3) + 2); - return; + /* This fires on all V86 interrupts in EMM386. Mark as expected to prevent code churn */ + if (cpu_state.eflags & VM_FLAG) + x86gpf_expected("pmodeint(): Expected vector descriptor with bad type", (num << 3) + 2); + else + x86gpf("pmodeint(): Vector descriptor with bad type", (num << 3) + 2); + return; } if ((DPL < CPL) && soft) { - x86gpf("pmodeint(): Vector DPL < CPL", (num << 3) + 2); - return; + x86gpf("pmodeint(): Vector DPL < CPL", (num << 3) + 2); + return; } type = segdat[2] & 0x1f00; if (((type == 0x0e00) || (type == 0x0f00)) && !is386) { - x86gpf("pmodeint(): Gate type illegal on 286", seg & 0xfffc); - return; + x86gpf("pmodeint(): Gate type illegal on 286", seg & 0xfffc); + return; } switch (type) { - case 0x0600: case 0x0700: case 0x0e00: case 0x0f00: /* Interrupt and trap gates */ - intgatesize = (type >= 0x0800) ? 32 : 16; - if (!(segdat[2] & 0x8000)) { - x86np("Int gate not present", (num << 3) | 2); - return; - } - seg = segdat[1]; - new_cpl = seg & 0x0003; + case 0x0600: + case 0x0700: + case 0x0e00: + case 0x0f00: /* Interrupt and trap gates */ + intgatesize = (type >= 0x0800) ? 32 : 16; + if (!(segdat[2] & 0x8000)) { + x86np("Int gate not present", (num << 3) | 2); + return; + } + seg = segdat[1]; + new_cpl = seg & 0x0003; - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - oaddr = addr; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("pmodeint(): Interrupt or trap gate selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + oaddr = addr; - if (DPL2 > CPL) { - x86gpf("pmodeint(): Interrupt or trap gate DPL > CPL", seg & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if (DPL2 < CPL) { - if (!(segdat2[2] & 0x8000)) { - x86np("Int gate CS not present", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && DPL2) { - x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode", segdat[1] & 0xfffc); - return; - } - /* Load new stack */ - oldss = SS; - oldsp = ESP; - cpl_override = 1; - if (tr.access & 8) { - addr = 4 + tr.base + (DPL2 << 3); - newss = readmemw(0, addr + 4); - newsp = readmeml(0, addr); - } else { - addr = 2 + tr.base + (DPL2 << 2); - newss = readmemw(0, addr + 2); - newsp = readmemw(0, addr); - } - cpl_override = 0; - if (!(newss & 0xfffc)) { - x86ss("pmodeint(): Interrupt or trap gate stack segment is NULL", newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat3, segdat332, 1); - if (cpu_state.abrt) - return; - if ((newss & 3) != DPL2) { - x86ss("pmodeint(): Interrupt or trap gate tack segment RPL > DPL",newss & 0xfffc); - return; - } - if (DPL3 != DPL2) { - x86ss("pmodeint(): Interrupt or trap gate tack segment DPL > DPL",newss & 0xfffc); - return; - } - if ((segdat3[2] & 0x1a00) != 0x1200) { - x86ss("pmodeint(): Interrupt or trap gate stack segment bad type", newss & 0xfffc); - return; - } - if (!(segdat3[2] & 0x8000)) { - x86np("Int gate loading SS not present", newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat3[3] & 0x0040) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat3); + if (DPL2 > CPL) { + x86gpf("pmodeint(): Interrupt or trap gate DPL > CPL", seg & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if (DPL2 < CPL) { + if (!(segdat2[2] & 0x8000)) { + x86np("Int gate CS not present", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && DPL2) { + x86gpf("pmodeint(): Interrupt or trap gate non-zero DPL in V86 mode", segdat[1] & 0xfffc); + return; + } + /* Load new stack */ + oldss = SS; + oldsp = ESP; + cpl_override = 1; + if (tr.access & 8) { + addr = 4 + tr.base + (DPL2 << 3); + newss = readmemw(0, addr + 4); + newsp = readmeml(0, addr); + } else { + addr = 2 + tr.base + (DPL2 << 2); + newss = readmemw(0, addr + 2); + newsp = readmemw(0, addr); + } + cpl_override = 0; + if (!(newss & 0xfffc)) { + x86ss("pmodeint(): Interrupt or trap gate stack segment is NULL", newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ss("pmodeint(): Interrupt or trap gate stack segment > DT", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat3, segdat332, 1); + if (cpu_state.abrt) + return; + if ((newss & 3) != DPL2) { + x86ss("pmodeint(): Interrupt or trap gate tack segment RPL > DPL", newss & 0xfffc); + return; + } + if (DPL3 != DPL2) { + x86ss("pmodeint(): Interrupt or trap gate tack segment DPL > DPL", newss & 0xfffc); + return; + } + if ((segdat3[2] & 0x1a00) != 0x1200) { + x86ss("pmodeint(): Interrupt or trap gate stack segment bad type", newss & 0xfffc); + return; + } + if (!(segdat3[2] & 0x8000)) { + x86np("Int gate loading SS not present", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat3[3] & 0x0040) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat3); - cpl_override = 1; - writememw(0, addr + 4, segdat3[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, addr + 4, segdat3[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - x86seg_log("New stack %04X:%08X\n", SS, ESP); - cpl_override = 1; - if (type >= 0x0800) { - if (cpu_state.eflags & VM_FLAG) { - PUSHL(GS); - PUSHL(FS); - PUSHL(DS); - PUSHL(ES); - if (cpu_state.abrt) - return; - loadseg(0, &cpu_state.seg_ds); - loadseg(0, &cpu_state.seg_es); - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } - PUSHL(oldss); - PUSHL(oldsp); - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(oldss); - PUSHW(oldsp); - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - cpl_override = 0; - cpu_state.seg_cs.access = 0x80; - cycles -= timing_int_pm_outer - timing_int_pm; - break; - } else if (DPL2 != CPL) { - x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); - return; - } - /*FALLTHROUGH*/ - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if (!(segdat2[2] & 0x8000)) { - x86np("Int gate CS not present", segdat[1] & 0xfffc); - return; - } - if ((cpu_state.eflags & VM_FLAG) && (DPL2 < CPL)) { - x86gpf("pmodeint(): DPL < CPL in V86 mode", seg &~ 0xfffc); - return; - } - if (type > 0x0800) { - PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); - PUSHL(CS); - PUSHL(cpu_state.pc); - if (cpu_state.abrt) - return; - } else { - PUSHW(cpu_state.flags); - PUSHW(CS); - PUSHW(cpu_state.pc); - if (cpu_state.abrt) - return; - } - new_cpl = CS & 3; - break; - default: - x86gpf("pmodeint(): Unknown type", seg & 0xfffc); - return; - } - do_seg_load(&cpu_state.seg_cs, segdat2); - CS = (seg & 0xfffc) | new_cpl; - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (new_cpl << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + x86seg_log("New stack %04X:%08X\n", SS, ESP); + cpl_override = 1; + if (type >= 0x0800) { + if (cpu_state.eflags & VM_FLAG) { + PUSHL(GS); + PUSHL(FS); + PUSHL(DS); + PUSHL(ES); + if (cpu_state.abrt) + return; + loadseg(0, &cpu_state.seg_ds); + loadseg(0, &cpu_state.seg_es); + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } + PUSHL(oldss); + PUSHL(oldsp); + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + PUSHL(CS); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(oldss); + PUSHW(oldsp); + PUSHW(cpu_state.flags); + PUSHW(CS); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + cpl_override = 0; + cpu_state.seg_cs.access = 0x80; + cycles -= timing_int_pm_outer - timing_int_pm; + break; + } else if (DPL2 != CPL) { + x86gpf("pmodeint(): DPL != CPL", seg & 0xfffc); + return; + } + /*FALLTHROUGH*/ + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if (!(segdat2[2] & 0x8000)) { + x86np("Int gate CS not present", segdat[1] & 0xfffc); + return; + } + if ((cpu_state.eflags & VM_FLAG) && (DPL2 < CPL)) { + x86gpf("pmodeint(): DPL < CPL in V86 mode", seg & ~0xfffc); + return; + } + if (type > 0x0800) { + PUSHL(cpu_state.flags | (cpu_state.eflags << 16)); + PUSHL(CS); + PUSHL(cpu_state.pc); + if (cpu_state.abrt) + return; + } else { + PUSHW(cpu_state.flags); + PUSHW(CS); + PUSHW(cpu_state.pc); + if (cpu_state.abrt) + return; + } + new_cpl = CS & 3; + break; + default: + x86gpf("pmodeint(): Unknown type", seg & 0xfffc); + return; + } + do_seg_load(&cpu_state.seg_cs, segdat2); + CS = (seg & 0xfffc) | new_cpl; + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | (new_cpl << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - if (type > 0x0800) - cpu_state.pc = segdat[0] | (segdat[3] << 16); - else - cpu_state.pc = segdat[0]; - set_use32(segdat2[3] & 0x40); + if (type > 0x0800) + cpu_state.pc = segdat[0] | (segdat[3] << 16); + else + cpu_state.pc = segdat[0]; + set_use32(segdat2[3] & 0x40); - cpl_override = 1; - writememw(0, oaddr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; + cpl_override = 1; + writememw(0, oaddr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; - cpu_state.eflags &= ~VM_FLAG; - cpu_cur_status &= ~CPU_STATUS_V86; - if (!(type & 0x100)) - cpu_state.flags &= ~I_FLAG; - cpu_state.flags &= ~(T_FLAG | NT_FLAG); - cycles -= timing_int_pm; - break; + cpu_state.eflags &= ~VM_FLAG; + cpu_cur_status &= ~CPU_STATUS_V86; + if (!(type & 0x100)) + cpu_state.flags &= ~I_FLAG; + cpu_state.flags &= ~(T_FLAG | NT_FLAG); + cycles -= timing_int_pm; + break; - case 0x500: /* Task gate */ - seg = segdat[1]; - addr = seg & 0xfff8; - dt = (seg & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) - return; - if (!(segdat2[2] & 0x8000)) { - x86np("Int task gate not present", segdat[1] & 0xfffc); - return; - } - optype = OPTYPE_INT; - cpl_override = 1; - taskswitch286(seg, segdat2, segdat2[2] & 0x0800); - cpl_override = 0; - break; + case 0x500: /* Task gate */ + seg = segdat[1]; + addr = seg & 0xfff8; + dt = (seg & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86gpf("pmodeint(): Task gate selector > DT limit", seg & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) + return; + if (!(segdat2[2] & 0x8000)) { + x86np("Int task gate not present", segdat[1] & 0xfffc); + return; + } + optype = OPTYPE_INT; + cpl_override = 1; + taskswitch286(seg, segdat2, segdat2[2] & 0x0800); + cpl_override = 0; + break; - default: - x86gpf("Protected mode interrupt unknown type", seg & 0xfffc); - return; + default: + x86gpf("Protected mode interrupt unknown type", seg & 0xfffc); + return; } } - void pmodeiret(int is32) { - uint16_t newss, seg = 0; - uint16_t segdat[4],segdat2[4]; - uint16_t segs[4]; - uint32_t tempflags, flagmask; - uint32_t newpc, newsp; - uint32_t addr, oaddr; - uint32_t oldsp = ESP; - uint32_t *segdat32 = (uint32_t *) segdat; + uint16_t newss, seg = 0; + uint16_t segdat[4], segdat2[4]; + uint16_t segs[4]; + uint32_t tempflags, flagmask; + uint32_t newpc, newsp; + uint32_t addr, oaddr; + uint32_t oldsp = ESP; + uint32_t *segdat32 = (uint32_t *) segdat; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; if (is386 && (cpu_state.eflags & VM_FLAG)) { - if (IOPL != 3) { - x86gpf("Protected mode IRET: IOPL != 3", 0); - return; - } + if (IOPL != 3) { + x86gpf("Protected mode IRET: IOPL != 3", 0); + return; + } #ifndef USE_NEW_DYNAREC - oxpc = cpu_state.pc; + oxpc = cpu_state.pc; #endif - if (is32) { - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - } - if (cpu_state.abrt) - return; + if (is32) { + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + } else { + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + } + if (cpu_state.abrt) + return; - cpu_state.pc = newpc; - cpu_state.seg_cs.base= seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - cpu_state.seg_cs.access |= 0x80; - cpu_state.seg_cs.ar_high = 0x10; - CS = seg; - cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xcfd5) | 2; - cycles -= timing_iret_rm; - return; + cpu_state.pc = newpc; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + cpu_state.seg_cs.access |= 0x80; + cpu_state.seg_cs.ar_high = 0x10; + CS = seg; + cpu_state.flags = (cpu_state.flags & 0x3000) | (tempflags & 0xcfd5) | 2; + cycles -= timing_iret_rm; + return; } if (cpu_state.flags & NT_FLAG) { - seg = readmemw(tr.base, 0); - addr = seg & 0xfff8; - if (seg & 0x0004) { - x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); - x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); - return; - } else { - if ((addr + 7) > gdt.limit) { - x86ts(NULL,seg & 0xfffc); - return; - } - addr += gdt.base; - } - cpl_override = 1; - read_descriptor(addr, segdat, segdat32, 1); - taskswitch286(seg, segdat,segdat[2] & 0x0800); - cpl_override = 0; - return; + seg = readmemw(tr.base, 0); + addr = seg & 0xfff8; + if (seg & 0x0004) { + x86seg_log("TS LDT %04X %04X IRET\n", seg, gdt.limit); + x86ts("pmodeiret(): Selector points to LDT", seg & 0xfffc); + return; + } else { + if ((addr + 7) > gdt.limit) { + x86ts(NULL, seg & 0xfffc); + return; + } + addr += gdt.base; + } + cpl_override = 1; + read_descriptor(addr, segdat, segdat32, 1); + taskswitch286(seg, segdat, segdat[2] & 0x0800); + cpl_override = 0; + return; } #ifndef USE_NEW_DYNAREC - oxpc=cpu_state.pc; + oxpc = cpu_state.pc; #endif flagmask = 0xffff; if (CPL != 0) - flagmask &= ~0x3000; + flagmask &= ~0x3000; if (IOPL < CPL) - flagmask &= ~0x200; + flagmask &= ~0x200; if (is32) { - newpc = POPL(); - seg = POPL(); - tempflags = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - if (is386 && ((tempflags >> 16) & VM_FLAG)) { - newsp = POPL(); - newss = POPL(); - segs[0] = POPL(); - segs[1] = POPL(); - segs[2] = POPL(); - segs[3] = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - cpu_state.eflags = tempflags >> 16; - cpu_cur_status |= CPU_STATUS_V86; - loadseg(segs[0], &cpu_state.seg_es); - do_seg_v86_init(&cpu_state.seg_es); - loadseg(segs[1], &cpu_state.seg_ds); - do_seg_v86_init(&cpu_state.seg_ds); - cpu_cur_status |= CPU_STATUS_NOTFLATDS; - loadseg(segs[2], &cpu_state.seg_fs); - do_seg_v86_init(&cpu_state.seg_fs); - loadseg(segs[3], &cpu_state.seg_gs); - do_seg_v86_init(&cpu_state.seg_gs); + newpc = POPL(); + seg = POPL(); + tempflags = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + if (is386 && ((tempflags >> 16) & VM_FLAG)) { + newsp = POPL(); + newss = POPL(); + segs[0] = POPL(); + segs[1] = POPL(); + segs[2] = POPL(); + segs[3] = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + cpu_state.eflags = tempflags >> 16; + cpu_cur_status |= CPU_STATUS_V86; + loadseg(segs[0], &cpu_state.seg_es); + do_seg_v86_init(&cpu_state.seg_es); + loadseg(segs[1], &cpu_state.seg_ds); + do_seg_v86_init(&cpu_state.seg_ds); + cpu_cur_status |= CPU_STATUS_NOTFLATDS; + loadseg(segs[2], &cpu_state.seg_fs); + do_seg_v86_init(&cpu_state.seg_fs); + loadseg(segs[3], &cpu_state.seg_gs); + do_seg_v86_init(&cpu_state.seg_gs); - cpu_state.pc = newpc & 0xffff; - cpu_state.seg_cs.base = seg << 4; - cpu_state.seg_cs.limit = 0xffff; - cpu_state.seg_cs.limit_low = 0; - cpu_state.seg_cs.limit_high = 0xffff; - CS = seg; - cpu_state.seg_cs.access = 0xe2; - cpu_state.seg_cs.ar_high = 0x10; - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + cpu_state.pc = newpc & 0xffff; + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.limit = 0xffff; + cpu_state.seg_cs.limit_low = 0; + cpu_state.seg_cs.limit_high = 0xffff; + CS = seg; + cpu_state.seg_cs.access = 0xe2; + cpu_state.seg_cs.ar_high = 0x10; + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - ESP = newsp; - loadseg(newss, &cpu_state.seg_ss); - do_seg_v86_init(&cpu_state.seg_ss); - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - cpu_state.flags = (tempflags & 0xffd5) | 2; - cycles -= timing_iret_v86; - return; - } + ESP = newsp; + loadseg(newss, &cpu_state.seg_ss); + do_seg_v86_init(&cpu_state.seg_ss); + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + cpu_state.flags = (tempflags & 0xffd5) | 2; + cycles -= timing_iret_v86; + return; + } } else { - newpc = POPW(); - seg = POPW(); - tempflags = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } + newpc = POPW(); + seg = POPW(); + tempflags = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } } if (!(seg & 0xfffc)) { - ESP = oldsp; - x86gpf("pmodeiret(): Selector is NULL", 0); - return; + ESP = oldsp; + x86gpf("pmodeiret(): Selector is NULL", 0); + return; } addr = seg & 0xfff8; - dt = (seg & 0x0004) ? & ldt : &gdt; + dt = (seg & 0x0004) ? &ldt : &gdt; if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmodeiret(): Selector > DT limit", seg & 0xfffc); + return; } addr += dt->base; if ((seg & 0x0003) < CPL) { - ESP = oldsp; - x86gpf("pmodeiret(): RPL < CPL", seg & 0xfffc); - return; + ESP = oldsp; + x86gpf("pmodeiret(): RPL < CPL", seg & 0xfffc); + return; } read_descriptor(addr, segdat, segdat32, 1); if (cpu_state.abrt) { - ESP = oldsp; - return; + ESP = oldsp; + return; } switch (segdat[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming code */ - if ((seg & 0x0003) != DPL) { - ESP = oldsp; - x86gpf("pmodeiret(): Non-conforming RPL != DPL", seg & 0xfffc); - return; - } - break; - case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /* Conforming code */ - if ((seg & 0x0003) < DPL) { - ESP = oldsp; - x86gpf("pmodeiret(): Conforming RPL < DPL",seg&~3); - return; - } - break; - default: - ESP = oldsp; - x86gpf("pmodeiret(): Unknown type", seg & 0xfffc); - return; + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming code */ + if ((seg & 0x0003) != DPL) { + ESP = oldsp; + x86gpf("pmodeiret(): Non-conforming RPL != DPL", seg & 0xfffc); + return; + } + break; + case 0x1C00: + case 0x1D00: + case 0x1E00: + case 0x1F00: /* Conforming code */ + if ((seg & 0x0003) < DPL) { + ESP = oldsp; + x86gpf("pmodeiret(): Conforming RPL < DPL", seg & ~3); + return; + } + break; + default: + ESP = oldsp; + x86gpf("pmodeiret(): Unknown type", seg & 0xfffc); + return; } if (!(segdat[2] & 0x8000)) { - ESP = oldsp; - x86np("IRET CS not present", seg & 0xfffc); - return; + ESP = oldsp; + x86np("IRET CS not present", seg & 0xfffc); + return; } if ((seg & 0x0003) == CPL) { - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 0x0003) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 0x0003) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x0040); + set_use32(segdat[3] & 0x0040); - cpl_override = 1; - writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - cycles -= timing_iret_pm; - } else { /* Return to outer level */ - oaddr = addr; - x86seg_log("Outer level\n"); - if (is32) { - newsp = POPL(); - newss = POPL(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } else { - newsp = POPW(); - newss = POPW(); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - } + cpl_override = 1; + writememw(0, addr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + cycles -= timing_iret_pm; + } else { /* Return to outer level */ + oaddr = addr; + x86seg_log("Outer level\n"); + if (is32) { + newsp = POPL(); + newss = POPL(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } else { + newsp = POPW(); + newss = POPW(); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + } - x86seg_log("IRET load stack %04X:%04X\n", newss, newsp); + x86seg_log("IRET load stack %04X:%04X\n", newss, newsp); - if (!(newss & 0xfffc)) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS selector is zero", newss & 0xfffc); - return; - } - addr = newss & 0xfff8; - dt = (newss & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 1); - if (cpu_state.abrt) { - ESP = oldsp; - return; - } - if ((newss & 3) != (seg & 3)) { - SP = oldsp; - x86gpf("pmodeiret(): New SS RPL > CS RPL",newss & 0xfffc); - return; - } - if ((segdat2[2] & 0x1a00) != 0x1200) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS bad type", newss & 0xfffc); - return; - } - if (DPL2 != (seg & 0x0003)) { - ESP = oldsp; - x86gpf("pmodeiret(): New SS DPL != CS RPL",newss & 0xfffc); - return; - } - if (!(segdat2[2] & 0x8000)) { - ESP = oldsp; - x86np("IRET loading SS not present", newss & 0xfffc); - return; - } - SS = newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); - if (stack32) - ESP = newsp; - else - SP = newsp; - do_seg_load(&cpu_state.seg_ss, segdat2); + if (!(newss & 0xfffc)) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS selector is zero", newss & 0xfffc); + return; + } + addr = newss & 0xfff8; + dt = (newss & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS selector > DT limit", newss & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 1); + if (cpu_state.abrt) { + ESP = oldsp; + return; + } + if ((newss & 3) != (seg & 3)) { + SP = oldsp; + x86gpf("pmodeiret(): New SS RPL > CS RPL", newss & 0xfffc); + return; + } + if ((segdat2[2] & 0x1a00) != 0x1200) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS bad type", newss & 0xfffc); + return; + } + if (DPL2 != (seg & 0x0003)) { + ESP = oldsp; + x86gpf("pmodeiret(): New SS DPL != CS RPL", newss & 0xfffc); + return; + } + if (!(segdat2[2] & 0x8000)) { + ESP = oldsp; + x86np("IRET loading SS not present", newss & 0xfffc); + return; + } + SS = newss; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); + if (stack32) + ESP = newsp; + else + SP = newsp; + do_seg_load(&cpu_state.seg_ss, segdat2); - cpl_override = 1; - writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ - writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ - cpl_override = 0; - /* Conforming segments don't change CPL, so CPL = RPL */ - if (segdat[2] & 0x0400) - segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); + cpl_override = 1; + writememw(0, addr + 4, segdat2[2] | 0x100); /* Set accessed bit */ + writememw(0, oaddr + 4, segdat[2] | 0x100); /* Set accessed bit */ + cpl_override = 0; + /* Conforming segments don't change CPL, so CPL = RPL */ + if (segdat[2] & 0x0400) + segdat[2] = (segdat[2] & ~(3 << 13)) | ((seg & 3) << 13); - CS = seg; - do_seg_load(&cpu_state.seg_cs, segdat); - cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 3) << 5); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = seg; + do_seg_load(&cpu_state.seg_cs, segdat); + cpu_state.seg_cs.access = (cpu_state.seg_cs.access & ~0x60) | ((CS & 3) << 5); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat[3] & 0x40); + set_use32(segdat[3] & 0x40); - check_seg_valid(&cpu_state.seg_ds); - check_seg_valid(&cpu_state.seg_es); - check_seg_valid(&cpu_state.seg_fs); - check_seg_valid(&cpu_state.seg_gs); - cycles -= timing_iret_pm_outer; + check_seg_valid(&cpu_state.seg_ds); + check_seg_valid(&cpu_state.seg_es); + check_seg_valid(&cpu_state.seg_fs); + check_seg_valid(&cpu_state.seg_gs); + cycles -= timing_iret_pm_outer; } - cpu_state.pc = newpc; - cpu_state.flags = (cpu_state.flags &~ flagmask) | (tempflags & flagmask & 0xffd5) | 2; + cpu_state.pc = newpc; + cpu_state.flags = (cpu_state.flags & ~flagmask) | (tempflags & flagmask & 0xffd5) | 2; if (is32) - cpu_state.eflags = tempflags >> 16; + cpu_state.eflags = tempflags >> 16; } - void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { - uint16_t tempw, new_ldt; - uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; - uint16_t segdat2[4]; - uint32_t base, limit; - uint32_t templ, new_cr3 = 0; - uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; - uint32_t new_esi, new_edi, new_pc, new_flags, addr; + uint16_t tempw, new_ldt; + uint16_t new_es, new_cs, new_ss, new_ds, new_fs, new_gs; + uint16_t segdat2[4]; + uint32_t base, limit; + uint32_t templ, new_cr3 = 0; + uint32_t new_eax, new_ebx, new_ecx, new_edx, new_esp, new_ebp; + uint32_t new_esi, new_edi, new_pc, new_flags, addr; uint32_t *segdat232 = (uint32_t *) segdat2; - x86seg *dt; + x86seg *dt; - base = segdat[1] | ((segdat[2] & 0x00ff) << 16); + base = segdat[1] | ((segdat[2] & 0x00ff) << 16); limit = segdat[0]; if (is386) { - base |= (segdat[3] >> 8) << 24; - limit |= (segdat[3] & 0x000f) << 16; + base |= (segdat[3] >> 8) << 24; + limit |= (segdat[3] & 0x000f) << 16; } if (is32) { - if (limit < 103) { - x86ts("taskswitch286(): limit < 103", seg); - return; - } + if (limit < 103) { + x86ts("taskswitch286(): limit < 103", seg); + return; + } - if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw |= 0x0200; - if (tr.seg & 0x0004) - writememw(ldt.base, (seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw |= 0x0200; + if (tr.seg & 0x0004) + writememw(ldt.base, (seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; - cpu_386_flags_rebuild(); - writememl(tr.base, 0x1C, cr3); - writememl(tr.base, 0x20, cpu_state.pc); - writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); + cpu_386_flags_rebuild(); + writememl(tr.base, 0x1C, cr3); + writememl(tr.base, 0x20, cpu_state.pc); + writememl(tr.base, 0x24, cpu_state.flags | (cpu_state.eflags << 16)); - writememl(tr.base, 0x28, EAX); - writememl(tr.base, 0x2C, ECX); - writememl(tr.base, 0x30, EDX); - writememl(tr.base, 0x34, EBX); - writememl(tr.base, 0x38, ESP); - writememl(tr.base, 0x3C, EBP); - writememl(tr.base, 0x40, ESI); - writememl(tr.base, 0x44, EDI); + writememl(tr.base, 0x28, EAX); + writememl(tr.base, 0x2C, ECX); + writememl(tr.base, 0x30, EDX); + writememl(tr.base, 0x34, EBX); + writememl(tr.base, 0x38, ESP); + writememl(tr.base, 0x3C, EBP); + writememl(tr.base, 0x40, ESI); + writememl(tr.base, 0x44, EDI); - writememl(tr.base, 0x48, ES); - writememl(tr.base, 0x4C, CS); - writememl(tr.base, 0x50, SS); - writememl(tr.base, 0x54, DS); - writememl(tr.base, 0x58, FS); - writememl(tr.base, 0x5C, GS); + writememl(tr.base, 0x48, ES); + writememl(tr.base, 0x4C, CS); + writememl(tr.base, 0x50, SS); + writememl(tr.base, 0x54, DS); + writememl(tr.base, 0x58, FS); + writememl(tr.base, 0x5C, GS); - if ((optype == JMP) || (optype == IRET)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw &= ~0x0200; - if (tr.seg & 0x0004) - writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == IRET)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw &= ~0x0200; + if (tr.seg & 0x0004) + writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if ((optype == OPTYPE_INT) || (optype == CALL)) { - writememl(base, 0, tr.seg); - if (cpu_state.abrt) - return; - } + if ((optype == OPTYPE_INT) || (optype == CALL)) { + writememl(base, 0, tr.seg); + if (cpu_state.abrt) + return; + } - new_cr3 = readmeml(base, 0x1C); - new_pc = readmeml(base, 0x20); - new_flags = readmeml(base, 0x24); - if ((optype == OPTYPE_INT) || (optype == CALL)) - new_flags |= NT_FLAG; + new_cr3 = readmeml(base, 0x1C); + new_pc = readmeml(base, 0x20); + new_flags = readmeml(base, 0x24); + if ((optype == OPTYPE_INT) || (optype == CALL)) + new_flags |= NT_FLAG; - new_eax = readmeml(base, 0x28); - new_ecx = readmeml(base, 0x2C); - new_edx = readmeml(base, 0x30); - new_ebx = readmeml(base, 0x34); - new_esp = readmeml(base, 0x38); - new_ebp = readmeml(base, 0x3C); - new_esi = readmeml(base, 0x40); - new_edi = readmeml(base, 0x44); + new_eax = readmeml(base, 0x28); + new_ecx = readmeml(base, 0x2C); + new_edx = readmeml(base, 0x30); + new_ebx = readmeml(base, 0x34); + new_esp = readmeml(base, 0x38); + new_ebp = readmeml(base, 0x3C); + new_esi = readmeml(base, 0x40); + new_edi = readmeml(base, 0x44); - new_es = readmemw(base, 0x48); - new_cs = readmemw(base, 0x4C); - new_ss = readmemw(base, 0x50); - new_ds = readmemw(base, 0x54); - new_fs = readmemw(base, 0x58); - new_gs = readmemw(base, 0x5C); - new_ldt = readmemw(base, 0x60); + new_es = readmemw(base, 0x48); + new_cs = readmemw(base, 0x4C); + new_ss = readmemw(base, 0x50); + new_ds = readmemw(base, 0x54); + new_fs = readmemw(base, 0x58); + new_gs = readmemw(base, 0x5C); + new_ldt = readmemw(base, 0x60); - cr0 |= 8; + cr0 |= 8; - cr3 = new_cr3; - flushmmucache(); + cr3 = new_cr3; + flushmmucache(); - cpu_state.pc = new_pc; - cpu_state.flags = new_flags; - cpu_state.eflags = new_flags >> 16; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + cpu_state.flags = new_flags; + cpu_state.eflags = new_flags >> 16; + cpu_386_flags_extract(); - ldt.seg = new_ldt; - templ = (ldt.seg & ~7) + gdt.base; - ldt.limit = readmemw(0, templ); - if (readmemb(0, templ + 6) & 0x80) { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); + ldt.seg = new_ldt; + templ = (ldt.seg & ~7) + gdt.base; + ldt.limit = readmemw(0, templ); + if (readmemb(0, templ + 6) & 0x80) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16) | (readmemb(0, templ + 7) << 24); - if (cpu_state.eflags & VM_FLAG) { - loadcs(new_cs); - set_use32(0); - cpu_cur_status |= CPU_STATUS_V86; - } else { - if (!(new_cs & 0xfffc)) { - x86ts("taskswitch286(): New CS selector is null", 0); - return; - } - addr = new_cs & 0xfff8; - dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 0); - if (!(segdat2[2] & 0x8000)) { - x86np("TS loading CS not present", new_cs & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((new_cs & 0x0003) != DPL2) { - x86ts("TS loading CS RPL != DPL2", new_cs & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((new_cs & 0x0003) < DPL2) { - x86ts("TS loading CS RPL < DPL2", new_cs & 0xfffc); - return; - } - break; - default: - x86ts("TS loading CS unknown type", new_cs & 0xfffc); - return; - } + if (cpu_state.eflags & VM_FLAG) { + loadcs(new_cs); + set_use32(0); + cpu_cur_status |= CPU_STATUS_V86; + } else { + if (!(new_cs & 0xfffc)) { + x86ts("taskswitch286(): New CS selector is null", 0); + return; + } + addr = new_cs & 0xfff8; + dt = (new_cs & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ts("taskswitch286(): New CS selector > DT limit", new_cs & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 0); + if (!(segdat2[2] & 0x8000)) { + x86np("TS loading CS not present", new_cs & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((new_cs & 0x0003) != DPL2) { + x86ts("TS loading CS RPL != DPL2", new_cs & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((new_cs & 0x0003) < DPL2) { + x86ts("TS loading CS RPL < DPL2", new_cs & 0xfffc); + return; + } + break; + default: + x86ts("TS loading CS unknown type", new_cs & 0xfffc); + return; + } - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(segdat2[3] & 0x0040); - cpu_cur_status &= ~CPU_STATUS_V86; - } + set_use32(segdat2[3] & 0x0040); + cpu_cur_status &= ~CPU_STATUS_V86; + } - EAX = new_eax; - ECX = new_ecx; - EDX = new_edx; - EBX = new_ebx; - ESP = new_esp; - EBP = new_ebp; - ESI = new_esi; - EDI = new_edi; + EAX = new_eax; + ECX = new_ecx; + EDX = new_edx; + EBX = new_ebx; + ESP = new_esp; + EBP = new_ebp; + ESI = new_esi; + EDI = new_edi; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); - loadseg(new_fs, &cpu_state.seg_fs); - loadseg(new_gs, &cpu_state.seg_gs); + loadseg(new_es, &cpu_state.seg_es); + loadseg(new_ss, &cpu_state.seg_ss); + loadseg(new_ds, &cpu_state.seg_ds); + loadseg(new_fs, &cpu_state.seg_fs); + loadseg(new_gs, &cpu_state.seg_gs); } else { - if (limit < 43) { - x86ts(NULL, seg); - return; - } + if (limit < 43) { + x86ts(NULL, seg); + return; + } - if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw |= 0x200; - if (tr.seg & 0x0004) - writememw(ldt.base, (seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == CALL) || (optype == OPTYPE_INT)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw |= 0x200; + if (tr.seg & 0x0004) + writememw(ldt.base, (seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if (optype == IRET) - cpu_state.flags &= ~NT_FLAG; + if (optype == IRET) + cpu_state.flags &= ~NT_FLAG; - cpu_386_flags_rebuild(); - writememw(tr.base, 0x0e, cpu_state.pc); - writememw(tr.base, 0x10, cpu_state.flags); + cpu_386_flags_rebuild(); + writememw(tr.base, 0x0e, cpu_state.pc); + writememw(tr.base, 0x10, cpu_state.flags); - writememw(tr.base, 0x12, AX); - writememw(tr.base, 0x14, CX); - writememw(tr.base, 0x16, DX); - writememw(tr.base, 0x18, BX); - writememw(tr.base, 0x1a, SP); - writememw(tr.base, 0x1c, BP); - writememw(tr.base, 0x1e, SI); - writememw(tr.base, 0x20, DI); + writememw(tr.base, 0x12, AX); + writememw(tr.base, 0x14, CX); + writememw(tr.base, 0x16, DX); + writememw(tr.base, 0x18, BX); + writememw(tr.base, 0x1a, SP); + writememw(tr.base, 0x1c, BP); + writememw(tr.base, 0x1e, SI); + writememw(tr.base, 0x20, DI); - writememw(tr.base, 0x22, ES); - writememw(tr.base, 0x24, CS); - writememw(tr.base, 0x26, SS); - writememw(tr.base, 0x28, DS); + writememw(tr.base, 0x22, ES); + writememw(tr.base, 0x24, CS); + writememw(tr.base, 0x26, SS); + writememw(tr.base, 0x28, DS); - if ((optype == JMP) || (optype == IRET)) { - if (tr.seg & 0x0004) - tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); - else - tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); - if (cpu_state.abrt) - return; - tempw &= ~0x200; - if (tr.seg & 0x0004) - writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); - else - writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); - } - if (cpu_state.abrt) - return; + if ((optype == JMP) || (optype == IRET)) { + if (tr.seg & 0x0004) + tempw = readmemw(ldt.base, (tr.seg & 0xfff8) + 4); + else + tempw = readmemw(gdt.base, (tr.seg & 0xfff8) + 4); + if (cpu_state.abrt) + return; + tempw &= ~0x200; + if (tr.seg & 0x0004) + writememw(ldt.base, (tr.seg & 0xfff8) + 4, tempw); + else + writememw(gdt.base, (tr.seg & 0xfff8) + 4, tempw); + } + if (cpu_state.abrt) + return; - if ((optype == OPTYPE_INT) || (optype == CALL)) { - writememw(base, 0, tr.seg); - if (cpu_state.abrt) - return; - } + if ((optype == OPTYPE_INT) || (optype == CALL)) { + writememw(base, 0, tr.seg); + if (cpu_state.abrt) + return; + } - new_pc = readmemw(base, 0x0e); - new_flags = readmemw(base, 0x10); - if ((optype == OPTYPE_INT) || (optype == CALL)) - new_flags |= NT_FLAG; + new_pc = readmemw(base, 0x0e); + new_flags = readmemw(base, 0x10); + if ((optype == OPTYPE_INT) || (optype == CALL)) + new_flags |= NT_FLAG; - new_eax = readmemw(base, 0x12); - new_ecx = readmemw(base, 0x14); - new_edx = readmemw(base, 0x16); - new_ebx = readmemw(base, 0x18); - new_esp = readmemw(base, 0x1a); - new_ebp = readmemw(base, 0x1c); - new_esi = readmemw(base, 0x1e); - new_edi = readmemw(base, 0x20); + new_eax = readmemw(base, 0x12); + new_ecx = readmemw(base, 0x14); + new_edx = readmemw(base, 0x16); + new_ebx = readmemw(base, 0x18); + new_esp = readmemw(base, 0x1a); + new_ebp = readmemw(base, 0x1c); + new_esi = readmemw(base, 0x1e); + new_edi = readmemw(base, 0x20); - new_es = readmemw(base, 0x22); - new_cs = readmemw(base, 0x24); - new_ss = readmemw(base, 0x26); - new_ds = readmemw(base, 0x28); - new_ldt = readmemw(base, 0x2a); + new_es = readmemw(base, 0x22); + new_cs = readmemw(base, 0x24); + new_ss = readmemw(base, 0x26); + new_ds = readmemw(base, 0x28); + new_ldt = readmemw(base, 0x2a); - msw |= 8; + msw |= 8; - cpu_state.pc = new_pc; - cpu_state.flags = new_flags; - cpu_386_flags_extract(); + cpu_state.pc = new_pc; + cpu_state.flags = new_flags; + cpu_386_flags_extract(); - ldt.seg = new_ldt; - templ = (ldt.seg & 0xfff8) + gdt.base; - ldt.limit = readmemw(0, templ); - ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16); - if (is386) { - if (readmemb(0, templ + 6) & 0x80) { - ldt.limit <<= 12; - ldt.limit |= 0xfff; - } - ldt.base |= (readmemb(0, templ + 7) << 24); - } + ldt.seg = new_ldt; + templ = (ldt.seg & 0xfff8) + gdt.base; + ldt.limit = readmemw(0, templ); + ldt.base = (readmemw(0, templ + 2)) | (readmemb(0, templ + 4) << 16); + if (is386) { + if (readmemb(0, templ + 6) & 0x80) { + ldt.limit <<= 12; + ldt.limit |= 0xfff; + } + ldt.base |= (readmemb(0, templ + 7) << 24); + } - if (!(new_cs & 0xfff8)) { - x86ts(NULL, 0); - return; - } - addr = new_cs & 0xfff8; - dt = (new_cs & 0x0004) ? &ldt : &gdt; - if ((addr + 7) > dt->limit) { - x86ts(NULL, new_cs & 0xfffc); - return; - } - addr += dt->base; - read_descriptor(addr, segdat2, segdat232, 0); - if (!(segdat2[2] & 0x8000)) { - x86np("TS loading CS not present", new_cs & 0xfffc); - return; - } - switch (segdat2[2] & 0x1f00) { - case 0x1800: case 0x1900: case 0x1a00: case 0x1b00: /* Non-conforming */ - if ((new_cs & 0x0003) != DPL2) { - x86ts(NULL,new_cs & 0xfffc); - return; - } - break; - case 0x1c00: case 0x1d00: case 0x1e00: case 0x1f00: /* Conforming */ - if ((new_cs & 0x0003) < DPL2) { - x86ts(NULL,new_cs & 0xfffc); - return; - } - break; - default: - x86ts(NULL, new_cs & 0xfffc); - return; - } + if (!(new_cs & 0xfff8)) { + x86ts(NULL, 0); + return; + } + addr = new_cs & 0xfff8; + dt = (new_cs & 0x0004) ? &ldt : &gdt; + if ((addr + 7) > dt->limit) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + addr += dt->base; + read_descriptor(addr, segdat2, segdat232, 0); + if (!(segdat2[2] & 0x8000)) { + x86np("TS loading CS not present", new_cs & 0xfffc); + return; + } + switch (segdat2[2] & 0x1f00) { + case 0x1800: + case 0x1900: + case 0x1a00: + case 0x1b00: /* Non-conforming */ + if ((new_cs & 0x0003) != DPL2) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + break; + case 0x1c00: + case 0x1d00: + case 0x1e00: + case 0x1f00: /* Conforming */ + if ((new_cs & 0x0003) < DPL2) { + x86ts(NULL, new_cs & 0xfffc); + return; + } + break; + default: + x86ts(NULL, new_cs & 0xfffc); + return; + } - CS = new_cs; - do_seg_load(&cpu_state.seg_cs, segdat2); - if ((CPL == 3) && (oldcpl != 3)) - flushmmucache_cr3(); + CS = new_cs; + do_seg_load(&cpu_state.seg_cs, segdat2); + if ((CPL == 3) && (oldcpl != 3)) + flushmmucache_cr3(); #ifdef USE_NEW_DYNAREC - oldcpl = CPL; + oldcpl = CPL; #endif - set_use32(0); + set_use32(0); - EAX = new_eax | 0xffff0000; - ECX = new_ecx | 0xffff0000; - EDX = new_edx | 0xffff0000; - EBX = new_ebx | 0xffff0000; - ESP = new_esp | 0xffff0000; - EBP = new_ebp | 0xffff0000; - ESI = new_esi | 0xffff0000; - EDI = new_edi | 0xffff0000; + EAX = new_eax | 0xffff0000; + ECX = new_ecx | 0xffff0000; + EDX = new_edx | 0xffff0000; + EBX = new_ebx | 0xffff0000; + ESP = new_esp | 0xffff0000; + EBP = new_ebp | 0xffff0000; + ESI = new_esi | 0xffff0000; + EDI = new_edi | 0xffff0000; - loadseg(new_es, &cpu_state.seg_es); - loadseg(new_ss, &cpu_state.seg_ss); - loadseg(new_ds, &cpu_state.seg_ds); - if (is386) { - loadseg(0, &cpu_state.seg_fs); - loadseg(0, &cpu_state.seg_gs); - } + loadseg(new_es, &cpu_state.seg_es); + loadseg(new_ss, &cpu_state.seg_ss); + loadseg(new_ds, &cpu_state.seg_ds); + if (is386) { + loadseg(0, &cpu_state.seg_fs); + loadseg(0, &cpu_state.seg_gs); + } } - tr.seg = seg; - tr.base = base; - tr.limit = limit; - tr.access = segdat[2] >> 8; + tr.seg = seg; + tr.base = base; + tr.limit = limit; + tr.access = segdat[2] >> 8; tr.ar_high = segdat[3] & 0xff; } - void cyrix_write_seg_descriptor(uint32_t addr, x86seg *seg) { uint32_t limit_raw = seg->limit; if (seg->ar_high & 0x80) - limit_raw >>= 12; + limit_raw >>= 12; writememl(0, addr, (limit_raw & 0xffff) | (seg->base << 16)); - writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | - (limit_raw & 0xf0000) | (seg->ar_high << 16) | - (seg->base & 0xff000000)); + writememl(0, addr + 4, ((seg->base >> 16) & 0xff) | (seg->access << 8) | (limit_raw & 0xf0000) | (seg->ar_high << 16) | (seg->base & 0xff000000)); } - void cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) { @@ -2414,30 +2453,30 @@ cyrix_load_seg_descriptor(uint32_t addr, x86seg *seg) segdat[1] = readmemw(0, addr + 2); segdat[2] = readmemw(0, addr + 4); segdat[3] = readmemw(0, addr + 6); - selector = readmemw(0, addr+8); + selector = readmemw(0, addr + 8); if (!cpu_state.abrt) { - do_seg_load(seg, segdat); - seg->seg = selector; - seg->checked = 0; - if (seg == &cpu_state.seg_ds) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATDS; + do_seg_load(seg, segdat); + seg->seg = selector; + seg->checked = 0; + if (seg == &cpu_state.seg_ds) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATDS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATDS; #ifdef USE_DYNAREC - codegen_flat_ds = 0; + codegen_flat_ds = 0; #endif - } - if (seg == &cpu_state.seg_ss) { - if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) - cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; - else - cpu_cur_status |= CPU_STATUS_NOTFLATSS; - set_stack32((segdat[3] & 0x40) ? 1 : 0); + } + if (seg == &cpu_state.seg_ss) { + if (seg->base == 0 && seg->limit_low == 0 && seg->limit_high == 0xffffffff) + cpu_cur_status &= ~CPU_STATUS_NOTFLATSS; + else + cpu_cur_status |= CPU_STATUS_NOTFLATSS; + set_stack32((segdat[3] & 0x40) ? 1 : 0); #ifdef USE_DYNAREC - codegen_flat_ss = 0; + codegen_flat_ss = 0; #endif - } + } } } diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 1f05e8762..0b93af9da 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -16,117 +16,111 @@ #include "x87.h" #include "386_common.h" - -uint32_t x87_pc_off,x87_op_off; -uint16_t x87_pc_seg,x87_op_seg; - +uint32_t x87_pc_off, x87_op_off; +uint16_t x87_pc_seg, x87_op_seg; #ifdef ENABLE_FPU_LOG int fpu_do_log = ENABLE_FPU_LOG; - void fpu_log(const char *fmt, ...) { va_list ap; if (fpu_do_log) { - va_start(ap, fmt); - pclog_ex(fmt, ap); - va_end(ap); + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); } } #else -#define fpu_log(fmt, ...) +# define fpu_log(fmt, ...) #endif - #define X87_TAG_VALID 0 #define X87_TAG_ZERO 1 #define X87_TAG_INVALID 2 #define X87_TAG_EMPTY 3 #ifdef USE_NEW_DYNAREC -uint16_t x87_gettag(void) +uint16_t +x87_gettag(void) { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] == TAG_EMPTY) - ret |= X87_TAG_EMPTY << (c * 2); - else if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) - ret |= X87_TAG_ZERO << (c * 2); - else - ret |= X87_TAG_VALID << (c * 2); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] == TAG_EMPTY) + ret |= X87_TAG_EMPTY << (c * 2); + else if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else if (cpu_state.ST[c] == 0.0 && !cpu_state.ismmx) + ret |= X87_TAG_ZERO << (c * 2); + else + ret |= X87_TAG_VALID << (c * 2); + } - return ret; + return ret; } -void x87_settag(uint16_t new_tag) +void +x87_settag(uint16_t new_tag) { - int c; + int c; - for (c = 0; c < 8; c++) - { - int tag = (new_tag >> (c * 2)) & 3; + for (c = 0; c < 8; c++) { + int tag = (new_tag >> (c * 2)) & 3; - if (tag == X87_TAG_EMPTY) - cpu_state.tag[c] = TAG_EMPTY; - else if (tag == 2) - cpu_state.tag[c] = TAG_VALID | TAG_UINT64; - else - cpu_state.tag[c] = TAG_VALID; - } + if (tag == X87_TAG_EMPTY) + cpu_state.tag[c] = TAG_EMPTY; + else if (tag == 2) + cpu_state.tag[c] = TAG_VALID | TAG_UINT64; + else + cpu_state.tag[c] = TAG_VALID; + } } #else -uint16_t x87_gettag(void) +uint16_t +x87_gettag(void) { - uint16_t ret = 0; - int c; + uint16_t ret = 0; + int c; - for (c = 0; c < 8; c++) - { - if (cpu_state.tag[c] & TAG_UINT64) - ret |= 2 << (c*2); - else - ret |= (cpu_state.tag[c] << (c*2)); - } + for (c = 0; c < 8; c++) { + if (cpu_state.tag[c] & TAG_UINT64) + ret |= 2 << (c * 2); + else + ret |= (cpu_state.tag[c] << (c * 2)); + } - return ret; + return ret; } -void x87_settag(uint16_t new_tag) +void +x87_settag(uint16_t new_tag) { - cpu_state.tag[0] = new_tag & 3; - cpu_state.tag[1] = (new_tag >> 2) & 3; - cpu_state.tag[2] = (new_tag >> 4) & 3; - cpu_state.tag[3] = (new_tag >> 6) & 3; - cpu_state.tag[4] = (new_tag >> 8) & 3; - cpu_state.tag[5] = (new_tag >> 10) & 3; - cpu_state.tag[6] = (new_tag >> 12) & 3; - cpu_state.tag[7] = (new_tag >> 14) & 3; + cpu_state.tag[0] = new_tag & 3; + cpu_state.tag[1] = (new_tag >> 2) & 3; + cpu_state.tag[2] = (new_tag >> 4) & 3; + cpu_state.tag[3] = (new_tag >> 6) & 3; + cpu_state.tag[4] = (new_tag >> 8) & 3; + cpu_state.tag[5] = (new_tag >> 10) & 3; + cpu_state.tag[6] = (new_tag >> 12) & 3; + cpu_state.tag[7] = (new_tag >> 14) & 3; } #endif - #ifdef ENABLE_808X_LOG -void x87_dumpregs(void) +void +x87_dumpregs(void) { - if (cpu_state.ismmx) - { - fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); - fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); - } - else - { - fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n",cpu_state.ST[cpu_state.TOP],cpu_state.ST[(cpu_state.TOP+1)&7],cpu_state.ST[(cpu_state.TOP+2)&7],cpu_state.ST[(cpu_state.TOP+3)&7]); - fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n",cpu_state.ST[(cpu_state.TOP+4)&7],cpu_state.ST[(cpu_state.TOP+5)&7],cpu_state.ST[(cpu_state.TOP+6)&7],cpu_state.ST[(cpu_state.TOP+7)&7]); - } - fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); + if (cpu_state.ismmx) { + fpu_log("MM0=%016llX\tMM1=%016llX\tMM2=%016llX\tMM3=%016llX\n", cpu_state.MM[0].q, cpu_state.MM[1].q, cpu_state.MM[2].q, cpu_state.MM[3].q); + fpu_log("MM4=%016llX\tMM5=%016llX\tMM6=%016llX\tMM7=%016llX\n", cpu_state.MM[4].q, cpu_state.MM[5].q, cpu_state.MM[6].q, cpu_state.MM[7].q); + } else { + fpu_log("ST(0)=%f\tST(1)=%f\tST(2)=%f\tST(3)=%f\t\n", cpu_state.ST[cpu_state.TOP], cpu_state.ST[(cpu_state.TOP + 1) & 7], cpu_state.ST[(cpu_state.TOP + 2) & 7], cpu_state.ST[(cpu_state.TOP + 3) & 7]); + fpu_log("ST(4)=%f\tST(5)=%f\tST(6)=%f\tST(7)=%f\t\n", cpu_state.ST[(cpu_state.TOP + 4) & 7], cpu_state.ST[(cpu_state.TOP + 5) & 7], cpu_state.ST[(cpu_state.TOP + 6) & 7], cpu_state.ST[(cpu_state.TOP + 7) & 7]); + } + fpu_log("Status = %04X Control = %04X Tag = %04X\n", cpu_state.npxs, cpu_state.npxc, x87_gettag()); } #endif diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 48106c2e3..96ad835c8 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -1,43 +1,44 @@ -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) -extern uint32_t x87_pc_off,x87_op_off; -extern uint16_t x87_pc_seg,x87_op_seg; +extern uint32_t x87_pc_off, x87_op_off; +extern uint16_t x87_pc_seg, x87_op_seg; -static __inline void x87_set_mmx(void) +static __inline void +x87_set_mmx(void) { - uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *)cpu_state.tag; - *p = 0x0101010101010101ull; - cpu_state.ismmx = 1; + uint64_t *p; + cpu_state.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ull; + cpu_state.ismmx = 1; } -static __inline void x87_emms(void) +static __inline void +x87_emms(void) { - uint64_t *p; - p = (uint64_t *)cpu_state.tag; - *p = 0; - cpu_state.ismmx = 0; + uint64_t *p; + p = (uint64_t *) cpu_state.tag; + *p = 0; + cpu_state.ismmx = 0; } - uint16_t x87_gettag(void); -void x87_settag(uint16_t new_tag); +void x87_settag(uint16_t new_tag); -#define TAG_EMPTY 0 -#define TAG_VALID (1 << 0) +#define TAG_EMPTY 0 +#define TAG_VALID (1 << 0) /*Hack for FPU copy. If set then MM[].q contains the 64-bit integer loaded by FILD*/ #ifdef USE_NEW_DYNAREC -#define TAG_UINT64 (1 << 7) +# define TAG_UINT64 (1 << 7) #else -#define TAG_UINT64 (1 << 2) +# define TAG_UINT64 (1 << 2) #endif /*Old dynarec stuff.*/ -#define TAG_NOT_UINT64 0xfb +#define TAG_NOT_UINT64 0xfb #define X87_ROUNDING_NEAREST 0 #define X87_ROUNDING_DOWN 1 diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 64ea50a33..cb7a35323 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -24,443 +24,446 @@ #include #include "x87_timings.h" #ifdef _MSC_VER -# include +# include #endif #ifdef ENABLE_FPU_LOG -extern void fpu_log(const char *fmt, ...); +extern void fpu_log(const char *fmt, ...); #else -#ifndef fpu_log -#define fpu_log(fmt, ...) -#endif +# ifndef fpu_log +# define fpu_log(fmt, ...) +# endif #endif -static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO}; +static int rounding_modes[4] = { FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO }; -#define ST(x) cpu_state.ST[((cpu_state.TOP+(x))&7)] +#define ST(x) cpu_state.ST[((cpu_state.TOP + (x)) & 7)] -#define C0 (1<<8) -#define C1 (1<<9) -#define C2 (1<<10) -#define C3 (1<<14) +#define C0 (1 << 8) +#define C1 (1 << 9) +#define C2 (1 << 10) +#define C3 (1 << 14) #define STATUS_ZERODIVIDE 4 #if defined(_MSC_VER) && !defined(__clang__) -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 -# define X87_INLINE_ASM -# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 +# define X87_INLINE_ASM +# endif #else -# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ -# define X87_INLINE_ASM -# endif +# if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined _M_IX86 || defined _M_X64 || defined __amd64__ +# define X87_INLINE_ASM +# endif #endif #ifdef FPU_8087 -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - fpu_log("FPU : divide by zero\n"); \ - if (!(cpu_state.npxc & 0x80)) { \ - cpu_state.npxs |= 0x80; \ - nmi = 1; \ - } \ - return 1; \ - } \ - } \ - else \ - dst = src1 / (double)src2; \ +# define x87_div(dst, src1, src2) \ + do { \ + if (((double) src2) == 0.0) { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double) src2; \ + else { \ + fpu_log("FPU : divide by zero\n"); \ + if (!(cpu_state.npxc & 0x80)) { \ + cpu_state.npxs |= 0x80; \ + nmi = 1; \ + } \ + return 1; \ + } \ + } else \ + dst = src1 / (double) src2; \ } while (0) #else -#define x87_div(dst, src1, src2) do \ - { \ - if (((double)src2) == 0.0) \ - { \ - cpu_state.npxs |= STATUS_ZERODIVIDE; \ - if (cpu_state.npxc & STATUS_ZERODIVIDE) \ - dst = src1 / (double)src2; \ - else \ - { \ - fpu_log("FPU : divide by zero\n"); \ - picint(1 << 13); \ - return 1; \ - } \ - } \ - else \ - dst = src1 / (double)src2; \ +# define x87_div(dst, src1, src2) \ + do { \ + if (((double) src2) == 0.0) { \ + cpu_state.npxs |= STATUS_ZERODIVIDE; \ + if (cpu_state.npxc & STATUS_ZERODIVIDE) \ + dst = src1 / (double) src2; \ + else { \ + fpu_log("FPU : divide by zero\n"); \ + picint(1 << 13); \ + return 1; \ + } \ + } else \ + dst = src1 / (double) src2; \ } while (0) #endif -static __inline void x87_checkexceptions(void) +static __inline void +x87_checkexceptions(void) { } -static __inline void x87_push(double i) +static __inline void +x87_push(double i) { #ifdef USE_NEW_DYNAREC - cpu_state.TOP--; + cpu_state.TOP--; #else - cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - cpu_state.ST[cpu_state.TOP&7] = i; + cpu_state.ST[cpu_state.TOP & 7] = i; #ifdef USE_NEW_DYNAREC - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; #else - cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? TAG_VALID : 0; + cpu_state.tag[cpu_state.TOP & 7] = (i == 0.0) ? TAG_VALID : 0; #endif } -static __inline void x87_push_u64(uint64_t i) +static __inline void +x87_push_u64(uint64_t i) { - union - { - double d; - uint64_t ll; - } td; + union { + double d; + uint64_t ll; + } td; - td.ll = i; + td.ll = i; #ifdef USE_NEW_DYNAREC - cpu_state.TOP--; + cpu_state.TOP--; #else - cpu_state.TOP=(cpu_state.TOP-1)&7; + cpu_state.TOP = (cpu_state.TOP - 1) & 7; #endif - cpu_state.ST[cpu_state.TOP&7] = td.d; + cpu_state.ST[cpu_state.TOP & 7] = td.d; #ifdef USE_NEW_DYNAREC - cpu_state.tag[cpu_state.TOP&7] = TAG_VALID; + cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID; #else - cpu_state.tag[cpu_state.TOP&7] = (td.d == 0.0) ? TAG_VALID : 0; + cpu_state.tag[cpu_state.TOP & 7] = (td.d == 0.0) ? TAG_VALID : 0; #endif } -static __inline double x87_pop(void) +static __inline double +x87_pop(void) { - double t = cpu_state.ST[cpu_state.TOP&7]; - cpu_state.tag[cpu_state.TOP&7] = TAG_EMPTY; + double t = cpu_state.ST[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = TAG_EMPTY; #ifdef USE_NEW_DYNAREC - cpu_state.TOP++; + cpu_state.TOP++; #else - cpu_state.tag[cpu_state.TOP&7] |= TAG_UINT64; - cpu_state.TOP=(cpu_state.TOP+1)&7; + cpu_state.tag[cpu_state.TOP & 7] |= TAG_UINT64; + cpu_state.TOP = (cpu_state.TOP + 1) & 7; #endif - return t; + return t; } -static __inline int16_t x87_fround16(double b) +static __inline int16_t +x87_fround16(double b) { - int16_t a, c; + int16_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int16_t)floor(b); - c = (int16_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int16_t)floor(b); - case 2: /*Up*/ - return (int16_t)ceil(b); - case 3: /*Chop*/ - return (int16_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int16_t) floor(b); + c = (int16_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int16_t) floor(b); + case 2: /*Up*/ + return (int16_t) ceil(b); + case 3: /*Chop*/ + return (int16_t) b; + } - return 0; + return 0; } -static __inline int64_t x87_fround16_64(double b) +static __inline int64_t +x87_fround16_64(double b) { return (int64_t) x87_fround16(b); } -static __inline int32_t x87_fround32(double b) +static __inline int32_t +x87_fround32(double b) { - int32_t a, c; + int32_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int32_t)floor(b); - c = (int32_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int32_t)floor(b); - case 2: /*Up*/ - return (int32_t)ceil(b); - case 3: /*Chop*/ - return (int32_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int32_t) floor(b); + c = (int32_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int32_t) floor(b); + case 2: /*Up*/ + return (int32_t) ceil(b); + case 3: /*Chop*/ + return (int32_t) b; + } - return 0; + return 0; } -static __inline int64_t x87_fround32_64(double b) +static __inline int64_t +x87_fround32_64(double b) { return (int64_t) x87_fround32(b); } -static __inline int64_t x87_fround(double b) +static __inline int64_t +x87_fround(double b) { - int64_t a, c; + int64_t a, c; - switch ((cpu_state.npxc >> 10) & 3) - { - case 0: /*Nearest*/ - a = (int64_t)floor(b); - c = (int64_t)floor(b + 1.0); - if ((b - a) < (c - b)) - return a; - else if ((b - a) > (c - b)) - return c; - else - return (a & 1) ? c : a; - case 1: /*Down*/ - return (int64_t)floor(b); - case 2: /*Up*/ - return (int64_t)ceil(b); - case 3: /*Chop*/ - return (int64_t)b; - } + switch ((cpu_state.npxc >> 10) & 3) { + case 0: /*Nearest*/ + a = (int64_t) floor(b); + c = (int64_t) floor(b + 1.0); + if ((b - a) < (c - b)) + return a; + else if ((b - a) > (c - b)) + return c; + else + return (a & 1) ? c : a; + case 1: /*Down*/ + return (int64_t) floor(b); + case 2: /*Up*/ + return (int64_t) ceil(b); + case 3: /*Chop*/ + return (int64_t) b; + } - return 0LL; + return 0LL; } #include "x87_ops_conv.h" -static __inline double x87_ld80(void) +static __inline double +x87_ld80(void) { - x87_conv_t test; - test.eind.ll = readmeml(easeg,cpu_state.eaaddr); - test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; - test.begin = readmemw(easeg,cpu_state.eaaddr+8); - return x87_from80(&test); + x87_conv_t test; + test.eind.ll = readmeml(easeg, cpu_state.eaaddr); + test.eind.ll |= (uint64_t) readmeml(easeg, cpu_state.eaaddr + 4) << 32; + test.begin = readmemw(easeg, cpu_state.eaaddr + 8); + return x87_from80(&test); } -static __inline void x87_st80(double d) +static __inline void +x87_st80(double d) { - x87_conv_t test; - x87_to80(d, &test); - writememl(easeg,cpu_state.eaaddr,test.eind.ll & 0xffffffff); - writememl(easeg,cpu_state.eaaddr+4,test.eind.ll>>32); - writememw(easeg,cpu_state.eaaddr+8,test.begin); + x87_conv_t test; + x87_to80(d, &test); + writememl(easeg, cpu_state.eaaddr, test.eind.ll & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, test.eind.ll >> 32); + writememw(easeg, cpu_state.eaaddr + 8, test.begin); } -static __inline void x87_st_fsave(int reg) +static __inline void +x87_st_fsave(int reg) { - reg = (cpu_state.TOP + reg) & 7; + reg = (cpu_state.TOP + reg) & 7; - if (cpu_state.tag[reg] & TAG_UINT64) - { - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); - writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); - writememw(easeg, cpu_state.eaaddr + 8, 0x5555); - } - else - x87_st80(cpu_state.ST[reg]); + if (cpu_state.tag[reg] & TAG_UINT64) { + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[reg].q & 0xffffffff); + writememl(easeg, cpu_state.eaaddr + 4, cpu_state.MM[reg].q >> 32); + writememw(easeg, cpu_state.eaaddr + 8, 0x5555); + } else + x87_st80(cpu_state.ST[reg]); } -static __inline void x87_ld_frstor(int reg) +static __inline void +x87_ld_frstor(int reg) { - reg = (cpu_state.TOP + reg) & 7; + reg = (cpu_state.TOP + reg) & 7; - cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); - cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); + cpu_state.MM[reg].q = readmemq(easeg, cpu_state.eaaddr); + cpu_state.MM_w4[reg] = readmemw(easeg, cpu_state.eaaddr + 8); #ifdef USE_NEW_DYNAREC - if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] & TAG_UINT64)) #else - if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2)) + if ((cpu_state.MM_w4[reg] == 0x5555) && (cpu_state.tag[reg] == 2)) #endif - { + { #ifndef USE_NEW_DYNAREC - cpu_state.tag[reg] = TAG_UINT64; + cpu_state.tag[reg] = TAG_UINT64; #endif - cpu_state.ST[reg] = (double)cpu_state.MM[reg].q; - } - else - { + cpu_state.ST[reg] = (double) cpu_state.MM[reg].q; + } else { #ifdef USE_NEW_DYNAREC - cpu_state.tag[reg] &= ~TAG_UINT64; + cpu_state.tag[reg] &= ~TAG_UINT64; #endif - cpu_state.ST[reg] = x87_ld80(); - } + cpu_state.ST[reg] = x87_ld80(); + } } -static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) +static __inline void +x87_ldmmx(MMX_REG *r, uint16_t *w4) { - r->l[0] = readmeml(easeg, cpu_state.eaaddr); - r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - *w4 = readmemw(easeg, cpu_state.eaaddr + 8); + r->l[0] = readmeml(easeg, cpu_state.eaaddr); + r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + *w4 = readmemw(easeg, cpu_state.eaaddr + 8); } -static __inline void x87_stmmx(MMX_REG r) +static __inline void +x87_stmmx(MMX_REG r) { - writememl(easeg, cpu_state.eaaddr, r.l[0]); - writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); - writememw(easeg, cpu_state.eaaddr + 8, 0xffff); + writememl(easeg, cpu_state.eaaddr, r.l[0]); + writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); + writememw(easeg, cpu_state.eaaddr + 8, 0xffff); } #include -static __inline uint16_t x87_compare(double a, double b) +static __inline uint16_t +x87_compare(double a, double b) { #ifdef X87_INLINE_ASM - uint32_t result; - double ea = a, eb = b; - const uint64_t ia = 0x3fec1a6ff866a936ull; - const uint64_t ib = 0x3fec1a6ff866a938ull; + uint32_t result; + double ea = a, eb = b; + const uint64_t ia = 0x3fec1a6ff866a936ull; + const uint64_t ib = 0x3fec1a6ff866a938ull; - /* Hack to make CHKCOP happy. */ - if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) - return C3; + /* Hack to make CHKCOP happy. */ + if (!memcmp(&ea, &ia, 8) && !memcmp(&eb, &ib, 8)) + return C3; - if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && - ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - eb = ea; + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; -#if !defined(_MSC_VER) || defined(__clang__) - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); +# if !defined(_MSC_VER) || defined(__clang__) + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile("" + : + : + : "memory"); - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fcompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (ea), "m" (eb) - ); -#else - _ReadWriteBarrier(); - _asm - { + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m"(result) + : "m"(ea), "m"(eb)); +# else + _ReadWriteBarrier(); + _asm + { fld eb fld ea fclex fcompp fnstsw result - } -#endif + } +# endif - return result & (C0|C2|C3); + return result & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; - double ea = a, eb = b; + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; + double ea = a, eb = b; - if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && - ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) - eb = ea; + if ((fpu_type < FPU_287XL) && !(cpu_state.npxc & 0x1000) && ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + eb = ea; - if (ea == eb) - result |= C3; - else if (ea < eb) - result |= C0; + if (ea == eb) + result |= C3; + else if (ea < eb) + result |= C0; - return result; + return result; #endif } -static __inline uint16_t x87_ucompare(double a, double b) +static __inline uint16_t +x87_ucompare(double a, double b) { #ifdef X87_INLINE_ASM - uint32_t result; + uint32_t result; -#if !defined(_MSC_VER) || defined(__clang__) - /* Memory barrier, to force GCC to write to the input parameters - * before the compare rather than after */ - __asm volatile ("" : : : "memory"); +# if !defined(_MSC_VER) || defined(__clang__) + /* Memory barrier, to force GCC to write to the input parameters + * before the compare rather than after */ + __asm volatile("" + : + : + : "memory"); - __asm( - "fldl %2\n" - "fldl %1\n" - "fclex\n" - "fucompp\n" - "fnstsw %0\n" - : "=m" (result) - : "m" (a), "m" (b) - ); -#else - _ReadWriteBarrier(); - _asm - { + __asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fucompp\n" + "fnstsw %0\n" + : "=m"(result) + : "m"(a), "m"(b)); +# else + _ReadWriteBarrier(); + _asm + { fld b fld a fclex fcompp fnstsw result - } -#endif + } +# endif - return result & (C0|C2|C3); + return result & (C0 | C2 | C3); #else - /* Generic C version is known to give incorrect results in some - * situations, eg comparison of infinity (Unreal) */ - uint32_t result = 0; + /* Generic C version is known to give incorrect results in some + * situations, eg comparison of infinity (Unreal) */ + uint32_t result = 0; - if (a == b) - result |= C3; - else if (a < b) - result |= C0; + if (a == b) + result |= C3; + else if (a < b) + result |= C0; - return result; + return result; #endif } -typedef union -{ - float s; - uint32_t i; +typedef union { + float s; + uint32_t i; } x87_ts; -typedef union -{ - double d; - uint64_t i; +typedef union { + double d; + uint64_t i; } x87_td; #ifdef FPU_8087 -#define FP_ENTER() { \ - } +# define FP_ENTER() \ + { \ + } #else -#define FP_ENTER() do \ - { \ - if (cr0 & 0xc) \ - { \ - x86_int(7); \ - return 1; \ - } \ +# define FP_ENTER() \ + do { \ + if (cr0 & 0xc) { \ + x86_int(7); \ + return 1; \ + } \ } while (0) #endif #ifdef USE_NEW_DYNAREC -# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP&7] = TAG_VALID -# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID -# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP&7] = TAG_VALID | TAG_UINT64 -# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID +# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID +# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_VALID +# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP & 7] = TAG_VALID | TAG_UINT64 +# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] = TAG_VALID #else -# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64 -# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64 -# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; -# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 +# define FP_TAG_VALID cpu_state.tag[cpu_state.TOP] &= ~TAG_UINT64 +# define FP_TAG_VALID_F cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] &= ~TAG_UINT64 +# define FP_TAG_DEFAULT cpu_state.tag[cpu_state.TOP] |= TAG_UINT64; +# define FP_TAG_VALID_N cpu_state.tag[(cpu_state.TOP + 1) & 7] &= ~TAG_UINT64 #endif #include "x87_ops_arith.h" @@ -468,56 +471,55 @@ typedef union #include "x87_ops_loadstore.h" #ifndef FPU_8087 -static int op_nofpu_a16(uint32_t fetchdat) +static int +op_nofpu_a16(uint32_t fetchdat) { - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_16(fetchdat); - return 0; - } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } else { + fetch_ea_16(fetchdat); + return 0; + } } -static int op_nofpu_a32(uint32_t fetchdat) +static int +op_nofpu_a32(uint32_t fetchdat) { - if (cr0 & 0xc) - { - x86_int(7); - return 1; - } - else - { - fetch_ea_32(fetchdat); - return 0; - } + if (cr0 & 0xc) { + x86_int(7); + return 1; + } else { + fetch_ea_32(fetchdat); + return 0; + } } #endif #ifdef FPU_8087 -static int FPU_ILLEGAL_a16(uint32_t fetchdat) +static int +FPU_ILLEGAL_a16(uint32_t fetchdat) { - geteaw(); - wait(timing_rr, 0); - return 0; + geteaw(); + wait(timing_rr, 0); + return 0; } #else -static int FPU_ILLEGAL_a16(uint32_t fetchdat) +static int +FPU_ILLEGAL_a16(uint32_t fetchdat) { - fetch_ea_16(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; + fetch_ea_16(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } -static int FPU_ILLEGAL_a32(uint32_t fetchdat) +static int +FPU_ILLEGAL_a32(uint32_t fetchdat) { - fetch_ea_32(fetchdat); - CLOCK_CYCLES(timing_rr); - PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); - return 0; + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0, 0, 0, 0, 0); + return 0; } #endif @@ -774,7 +776,7 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; #else -#define ILLEGAL_a32 FPU_ILLEGAL_a32 +# define ILLEGAL_a32 FPU_ILLEGAL_a32 const OpFn OP_TABLE(fpu_d8_a16)[32] = { diff --git a/src/cpu/x87_ops_arith.h b/src/cpu/x87_ops_arith.h index 5e4bfceab..f5e5d7696 100644 --- a/src/cpu/x87_ops_arith.h +++ b/src/cpu/x87_ops_arith.h @@ -1,457 +1,508 @@ -#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ -static int opFADD ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ - ST(0) += use_var; \ - if ((cpu_state.npxc >> 10) & 3) \ - fesetround(FE_TONEAREST); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFCOM ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFCOMP ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - cpu_state.npxs &= ~(C0|C2|C3); \ - cpu_state.npxs |= x87_compare(ST(0), (double)use_var); \ - x87_pop(); \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom ## cycle_postfix) : ((x87_timings.fcom ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom ## cycle_postfix) : ((x87_concurrency.fcom ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFDIV ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), ST(0), use_var); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFDIVR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - x87_div(ST(0), use_var, ST(0)); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv ## cycle_postfix) : ((x87_timings.fdiv ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv ## cycle_postfix) : ((x87_concurrency.fdiv ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFMUL ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) *= use_var; \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul ## cycle_postfix) : ((x87_timings.fmul ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul ## cycle_postfix) : ((x87_concurrency.fmul ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFSUB ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) -= use_var; \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} \ -static int opFSUBR ## name ## _a ## a_size(uint32_t fetchdat) \ -{ \ - optype t; \ - FP_ENTER(); \ - fetch_ea_ ## a_size(fetchdat); \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - load_var = get(); if (cpu_state.abrt) return 1; \ - ST(0) = use_var - ST(0); \ - FP_TAG_VALID; \ - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd ## cycle_postfix) : ((x87_timings.fadd ## cycle_postfix) * cpu_multi)); \ - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd ## cycle_postfix) : ((x87_concurrency.fadd ## cycle_postfix) * cpu_multi)); \ - return 0; \ -} - +#define opFPU(name, optype, a_size, load_var, get, use_var, cycle_postfix) \ + static int opFADD##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(rounding_modes[(cpu_state.npxc >> 10) & 3]); \ + ST(0) += use_var; \ + if ((cpu_state.npxc >> 10) & 3) \ + fesetround(FE_TONEAREST); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFCOM##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFCOMP##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + cpu_state.npxs &= ~(C0 | C2 | C3); \ + cpu_state.npxs |= x87_compare(ST(0), (double) use_var); \ + x87_pop(); \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom##cycle_postfix) : ((x87_timings.fcom##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom##cycle_postfix) : ((x87_concurrency.fcom##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFDIV##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), ST(0), use_var); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFDIVR##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + x87_div(ST(0), use_var, ST(0)); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv##cycle_postfix) : ((x87_timings.fdiv##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv##cycle_postfix) : ((x87_concurrency.fdiv##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFMUL##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) *= use_var; \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul##cycle_postfix) : ((x87_timings.fmul##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul##cycle_postfix) : ((x87_concurrency.fmul##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFSUB##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) -= use_var; \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } \ + static int opFSUBR##name##_a##a_size(uint32_t fetchdat) \ + { \ + optype t; \ + FP_ENTER(); \ + fetch_ea_##a_size(fetchdat); \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + load_var = get(); \ + if (cpu_state.abrt) \ + return 1; \ + ST(0) = use_var - ST(0); \ + FP_TAG_VALID; \ + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd##cycle_postfix) : ((x87_timings.fadd##cycle_postfix) * cpu_multi)); \ + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd##cycle_postfix) : ((x87_concurrency.fadd##cycle_postfix) * cpu_multi)); \ + return 0; \ + } opFPU(s, x87_ts, 16, t.i, geteal, t.s, _32) #ifndef FPU_8087 -opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) + opFPU(s, x87_ts, 32, t.i, geteal, t.s, _32) #endif -opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) + opFPU(d, x87_td, 16, t.i, geteaq, t.d, _64) #ifndef FPU_8087 -opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) + opFPU(d, x87_td, 32, t.i, geteaq, t.d, _64) #endif -opFPU(iw, uint16_t, 16, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 16, t, geteaw, (double) (int16_t) t, _i16) #ifndef FPU_8087 -opFPU(iw, uint16_t, 32, t, geteaw, (double)(int16_t)t, _i16) + opFPU(iw, uint16_t, 32, t, geteaw, (double) (int16_t) t, _i16) #endif -opFPU(il, uint32_t, 16, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 16, t, geteal, (double) (int32_t) t, _i32) #ifndef FPU_8087 -opFPU(il, uint32_t, 32, t, geteal, (double)(int32_t)t, _i32) + opFPU(il, uint32_t, 32, t, geteal, (double) (int32_t) t, _i32) #endif - -static int opFADD(uint32_t fetchdat) + static int opFADD(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) + ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) + ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFADDr(uint32_t fetchdat) +static int +opFADDr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFADDP(uint32_t fetchdat) +static int +opFADDP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) + ST(0); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFCOM(uint32_t fetchdat) +static int +opFCOM(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == ST(fetchdat & 7)) cpu_state.npxs |= C3; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.npxs |= C0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.npxs |= C3; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.npxs |= C0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMP(uint32_t fetchdat) +static int +opFCOMP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_compare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMPP(uint32_t fetchdat) +static int +opFCOMPP(uint32_t fetchdat) { - uint64_t *p, *q; - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - p = (uint64_t *)&ST(0); - q = (uint64_t *)&ST(1); - if ((*p == ((uint64_t)1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) - cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ - else - cpu_state.npxs |= x87_compare(ST(0), ST(1)); + uint64_t *p, *q; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + p = (uint64_t *) &ST(0); + q = (uint64_t *) &ST(1); + if ((*p == ((uint64_t) 1 << 63) && *q == 0) && (fpu_type >= FPU_287XL)) + cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ + else + cpu_state.npxs |= x87_compare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + x87_pop(); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFUCOMPP(uint32_t fetchdat) +static int +opFUCOMPP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); - x87_pop(); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(1)); + x87_pop(); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFCOMI(uint32_t fetchdat) +static int +opFCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } -static int opFCOMIP(uint32_t fetchdat) +static int +opFCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fcom) : (x87_timings.fcom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fcom) : (x87_concurrency.fcom * cpu_multi)); + return 0; } #endif -static int opFDIV(uint32_t fetchdat) +static int +opFDIV(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(0), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVr(uint32_t fetchdat) +static int +opFDIVr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVP(uint32_t fetchdat) +static int +opFDIVP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVR(uint32_t fetchdat) +static int +opFDIVR(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(0), ST(fetchdat&7), ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(0), ST(fetchdat & 7), ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVRr(uint32_t fetchdat) +static int +opFDIVRr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFDIVRP(uint32_t fetchdat) +static int +opFDIVRP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + x87_div(ST(fetchdat & 7), ST(0), ST(fetchdat & 7)); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fdiv) : (x87_timings.fdiv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fdiv) : (x87_concurrency.fdiv * cpu_multi)); + return 0; } -static int opFMUL(uint32_t fetchdat) +static int +opFMUL(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFMULr(uint32_t fetchdat) +static int +opFMULr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFMULP(uint32_t fetchdat) +static int +opFMULP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) * ST(fetchdat & 7); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fmul) : (x87_timings.fmul * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fmul) : (x87_concurrency.fmul * cpu_multi)); + return 0; } -static int opFSUB(uint32_t fetchdat) +static int +opFSUB(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBr(uint32_t fetchdat) +static int +opFSUBr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBP(uint32_t fetchdat) +static int +opFSUBP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBR(uint32_t fetchdat) +static int +opFSUBR(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(0) = ST(fetchdat & 7) - ST(0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(0) = ST(fetchdat & 7) - ST(0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBRr(uint32_t fetchdat) +static int +opFSUBRr(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID_F; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID_F; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } -static int opFSUBRP(uint32_t fetchdat) +static int +opFSUBRP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); - FP_TAG_VALID_F; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0) - ST(fetchdat & 7); + FP_TAG_VALID_F; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fadd) : (x87_timings.fadd * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fadd) : (x87_concurrency.fadd * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFUCOM(uint32_t fetchdat) +static int +opFUCOM(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMP(uint32_t fetchdat) +static int +opFUCOMP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + cpu_state.npxs |= x87_ucompare(ST(0), ST(fetchdat & 7)); + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMI(uint32_t fetchdat) +static int +opFUCOMI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } -static int opFUCOMIP(uint32_t fetchdat) +static int +opFUCOMIP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - flags_rebuild(); - cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); - if (ST(0) == ST(fetchdat & 7)) cpu_state.flags |= Z_FLAG; - else if (ST(0) < ST(fetchdat & 7)) cpu_state.flags |= C_FLAG; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + flags_rebuild(); + cpu_state.flags &= ~(Z_FLAG | P_FLAG | C_FLAG); + if (ST(0) == ST(fetchdat & 7)) + cpu_state.flags |= Z_FLAG; + else if (ST(0) < ST(fetchdat & 7)) + cpu_state.flags |= C_FLAG; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fucom) : (x87_timings.fucom * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fucom) : (x87_concurrency.fucom * cpu_multi)); + return 0; } #endif diff --git a/src/cpu/x87_ops_conv.h b/src/cpu/x87_ops_conv.h index 44304c1bc..bb1e497da 100644 --- a/src/cpu/x87_ops_conv.h +++ b/src/cpu/x87_ops_conv.h @@ -4,65 +4,66 @@ typedef struct { int16_t begin; union { - double d; + double d; uint64_t ll; } eind; } x87_conv_t; -static __inline double x87_from80(x87_conv_t *test) +static __inline double +x87_from80(x87_conv_t *test) { - int64_t exp64; - int64_t blah; - int64_t exp64final; - int64_t mant64; - int64_t sign; + int64_t exp64; + int64_t blah; + int64_t exp64final; + int64_t mant64; + int64_t sign; - exp64 = (((test->begin&0x7fff) - BIAS80)); - blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + exp64 = (((test->begin & 0x7fff) - BIAS80)); + blah = ((exp64 > 0) ? exp64 : -exp64) & 0x3ff; + exp64final = ((exp64 > 0) ? blah : -blah) + BIAS64; - mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); - sign = (test->begin&0x8000)?1:0; + mant64 = (test->eind.ll >> 11) & (0xfffffffffffffll); + sign = (test->begin & 0x8000) ? 1 : 0; - if ((test->begin & 0x7fff) == 0x7fff) - exp64final = 0x7ff; - if ((test->begin & 0x7fff) == 0) - exp64final = 0; - if (test->eind.ll & 0x400) - mant64++; + if ((test->begin & 0x7fff) == 0x7fff) + exp64final = 0x7ff; + if ((test->begin & 0x7fff) == 0) + exp64final = 0; + if (test->eind.ll & 0x400) + mant64++; - test->eind.ll = (sign <<63)|(exp64final << 52)| mant64; + test->eind.ll = (sign << 63) | (exp64final << 52) | mant64; - return test->eind.d; + return test->eind.d; } -static __inline void x87_to80(double d, x87_conv_t *test) +static __inline void +x87_to80(double d, x87_conv_t *test) { - int64_t sign80; - int64_t exp80; - int64_t exp80final; - int64_t mant80; - int64_t mant80final; + int64_t sign80; + int64_t exp80; + int64_t exp80final; + int64_t mant80; + int64_t mant80final; - test->eind.d=d; + test->eind.d = d; - sign80 = (test->eind.ll&(0x8000000000000000ll))?1:0; - exp80 = test->eind.ll&(0x7ff0000000000000ll); - exp80final = (exp80>>52); - mant80 = test->eind.ll&(0x000fffffffffffffll); - mant80final = (mant80 << 11); + sign80 = (test->eind.ll & (0x8000000000000000ll)) ? 1 : 0; + exp80 = test->eind.ll & (0x7ff0000000000000ll); + exp80final = (exp80 >> 52); + mant80 = test->eind.ll & (0x000fffffffffffffll); + mant80final = (mant80 << 11); - if (exp80final == 0x7ff) /*Infinity / Nan*/ - { - exp80final = 0x7fff; - mant80final |= (0x8000000000000000ll); - } - else if (d != 0){ /* Zero is a special case */ - /* Elvira wants the 8 and tcalc doesn't */ - mant80final |= (0x8000000000000000ll); - /* Ca-cyber doesn't like this when result is zero. */ - exp80final += (BIAS80 - BIAS64); - } - test->begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; - test->eind.ll = mant80final; + if (exp80final == 0x7ff) /*Infinity / Nan*/ + { + exp80final = 0x7fff; + mant80final |= (0x8000000000000000ll); + } else if (d != 0) { /* Zero is a special case */ + /* Elvira wants the 8 and tcalc doesn't */ + mant80final |= (0x8000000000000000ll); + /* Ca-cyber doesn't like this when result is zero. */ + exp80final += (BIAS80 - BIAS64); + } + test->begin = (((int16_t) sign80) << 15) | (int16_t) exp80final; + test->eind.ll = mant80final; } diff --git a/src/cpu/x87_ops_loadstore.h b/src/cpu/x87_ops_loadstore.h index d36cf426b..8d3c3f700 100644 --- a/src/cpu/x87_ops_loadstore.h +++ b/src/cpu/x87_ops_loadstore.h @@ -16,496 +16,582 @@ * Copyright 2008-2019 Sarah Walker. * Copyright 2016-2019 Miran Grca. */ -static int opFILDiw_a16(uint32_t fetchdat) +static int +opFILDiw_a16(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - x87_push((double)temp); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDiw_a32(uint32_t fetchdat) +static int +opFILDiw_a32(uint32_t fetchdat) { - int16_t temp; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp = geteaw(); if (cpu_state.abrt) return 1; - x87_push((double)temp); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); - return 0; + int16_t temp; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp = geteaw(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_16) : (x87_timings.fild_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_16) : (x87_concurrency.fild_16 * cpu_multi)); + return 0; } #endif -static int opFISTiw_a16(uint32_t fetchdat) +static int +opFISTiw_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFISTiw_a32(uint32_t fetchdat) +static int +opFISTiw_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFISTPiw_a16(uint32_t fetchdat) +static int +opFISTPiw_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFISTPiw_a32(uint32_t fetchdat) +static int +opFISTPiw_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(x87_fround16(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(x87_fround16(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_16) : (x87_timings.fist_16 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_16) : (x87_concurrency.fist_16 * cpu_multi)); + return 0; } #endif -static int opFILDiq_a16(uint32_t fetchdat) +static int +opFILDiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP&7].q = temp64; - FP_TAG_DEFAULT; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp64); + cpu_state.MM[cpu_state.TOP & 7].q = temp64; + FP_TAG_DEFAULT; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDiq_a32(uint32_t fetchdat) +static int +opFILDiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - temp64 = geteaq(); if (cpu_state.abrt) return 1; - x87_push((double)temp64); - cpu_state.MM[cpu_state.TOP&7].q = temp64; - FP_TAG_DEFAULT; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + temp64 = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push((double) temp64); + cpu_state.MM[cpu_state.TOP & 7].q = temp64; + FP_TAG_DEFAULT; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_64) : (x87_timings.fild_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_64) : (x87_concurrency.fild_64 * cpu_multi)); + return 0; } #endif -static int FBSTP_a16(uint32_t fetchdat) +static int +FBSTP_a16(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) { + uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t) floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) + tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fbstp) : (x87_concurrency.fbstp * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int FBSTP_a32(uint32_t fetchdat) +static int +FBSTP_a32(uint32_t fetchdat) { - double tempd; - int c; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - tempd = ST(0); - if (tempd < 0.0) - tempd = -tempd; - for (c = 0; c < 9; c++) - { - uint8_t tempc = (uint8_t)floor(fmod(tempd, 10.0)); - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - tempc |= ((uint8_t)floor(fmod(tempd, 10.0))) << 4; - tempd -= floor(fmod(tempd, 10.0)); - tempd /= 10.0; - writememb(easeg, cpu_state.eaaddr + c, tempc); - } - tempc = (uint8_t)floor(fmod(tempd, 10.0)); - if (ST(0) < 0.0) tempc |= 0x80; - writememb(easeg, cpu_state.eaaddr + 9, tempc); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); - return 0; + double tempd; + int c; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + tempd = ST(0); + if (tempd < 0.0) + tempd = -tempd; + for (c = 0; c < 9; c++) { + uint8_t tempc = (uint8_t) floor(fmod(tempd, 10.0)); + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + tempc |= ((uint8_t) floor(fmod(tempd, 10.0))) << 4; + tempd -= floor(fmod(tempd, 10.0)); + tempd /= 10.0; + writememb(easeg, cpu_state.eaaddr + c, tempc); + } + tempc = (uint8_t) floor(fmod(tempd, 10.0)); + if (ST(0) < 0.0) + tempc |= 0x80; + writememb(easeg, cpu_state.eaaddr + 9, tempc); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fbstp) : (x87_timings.fbstp * cpu_multi)); + return 0; } #endif -static int FISTPiq_a16(uint32_t fetchdat) +static int +FISTPiq_a16(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP&7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int FISTPiq_a32(uint32_t fetchdat) +static int +FISTPiq_a32(uint32_t fetchdat) { - int64_t temp64; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - if (cpu_state.tag[cpu_state.TOP&7] & TAG_UINT64) - temp64 = cpu_state.MM[cpu_state.TOP&7].q; - else - temp64 = x87_fround(ST(0)); - seteaq(temp64); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); - return 0; + int64_t temp64; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + if (cpu_state.tag[cpu_state.TOP & 7] & TAG_UINT64) + temp64 = cpu_state.MM[cpu_state.TOP & 7].q; + else + temp64 = x87_fround(ST(0)); + seteaq(temp64); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_64) : (x87_timings.fist_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_64) : (x87_concurrency.fist_64 * cpu_multi)); + return 0; } #endif -static int opFILDil_a16(uint32_t fetchdat) +static int +opFILDil_a16(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)templ); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) templ); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFILDil_a32(uint32_t fetchdat) +static int +opFILDil_a32(uint32_t fetchdat) { - int32_t templ; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - templ = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)templ); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); - return 0; + int32_t templ; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + templ = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) templ); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fild_32) : (x87_timings.fild_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fild_32) : (x87_concurrency.fild_32 * cpu_multi)); + return 0; } #endif -static int opFISTil_a16(uint32_t fetchdat) +static int +opFISTil_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFISTil_a32(uint32_t fetchdat) +static int +opFISTil_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFISTPil_a16(uint32_t fetchdat) +static int +opFISTPil_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFISTPil_a32(uint32_t fetchdat) +static int +opFISTPil_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteal(x87_fround32(ST(0))); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteal(x87_fround32(ST(0))); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fist_32) : (x87_timings.fist_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fist_32) : (x87_concurrency.fist_32 * cpu_multi)); + return 0; } #endif -static int opFLDe_a16(uint32_t fetchdat) +static int +opFLDe_a16(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t=x87_ld80(); if (cpu_state.abrt) return 1; - x87_push(t); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + double t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t = x87_ld80(); + if (cpu_state.abrt) + return 1; + x87_push(t); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDe_a32(uint32_t fetchdat) +static int +opFLDe_a32(uint32_t fetchdat) { - double t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t=x87_ld80(); if (cpu_state.abrt) return 1; - x87_push(t); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + double t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t = x87_ld80(); + if (cpu_state.abrt) + return 1; + x87_push(t); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #endif -static int opFSTPe_a16(uint32_t fetchdat) +static int +opFSTPe_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPe_a32(uint32_t fetchdat) +static int +opFSTPe_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - x87_st80(ST(0)); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); - return 0; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + x87_st80(ST(0)); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_80) : (x87_timings.fld_80 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_80) : (x87_concurrency.fld_80 * cpu_multi)); + return 0; } #endif -static int opFLDd_a16(uint32_t fetchdat) +static int +opFLDd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t.i = geteaq(); if (cpu_state.abrt) return 1; - x87_push(t.d); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push(t.d); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDd_a32(uint32_t fetchdat) +static int +opFLDd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - t.i = geteaq(); if (cpu_state.abrt) return 1; - x87_push(t.d); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + t.i = geteaq(); + if (cpu_state.abrt) + return 1; + x87_push(t.d); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_64) : (x87_timings.fld_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_64) : (x87_concurrency.fld_64 * cpu_multi)); + return 0; } #endif -static int opFSTd_a16(uint32_t fetchdat) +static int +opFSTd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTd_a32(uint32_t fetchdat) +static int +opFSTd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return cpu_state.abrt; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFSTPd_a16(uint32_t fetchdat) +static int +opFSTPd_a16(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPd_a32(uint32_t fetchdat) +static int +opFSTPd_a32(uint32_t fetchdat) { - x87_td t; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - t.d = ST(0); - seteaq(t.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); - return 0; + x87_td t; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + t.d = ST(0); + seteaq(t.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_64) : (x87_timings.fst_64 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_64) : (x87_concurrency.fst_64 * cpu_multi)); + return 0; } #endif -static int opFLDs_a16(uint32_t fetchdat) +static int +opFLDs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - ts.i = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)ts.s); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) ts.s); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFLDs_a32(uint32_t fetchdat) +static int +opFLDs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - ts.i = geteal(); if (cpu_state.abrt) return 1; - x87_push((double)ts.s); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + ts.i = geteal(); + if (cpu_state.abrt) + return 1; + x87_push((double) ts.s); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #endif -static int opFSTs_a16(uint32_t fetchdat) +static int +opFSTs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTs_a32(uint32_t fetchdat) +static int +opFSTs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return cpu_state.abrt; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return cpu_state.abrt; } #endif -static int opFSTPs_a16(uint32_t fetchdat) +static int +opFSTPs_a16(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #ifndef FPU_8087 -static int opFSTPs_a32(uint32_t fetchdat) +static int +opFSTPs_a32(uint32_t fetchdat) { - x87_ts ts; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - ts.s = (float)ST(0); - seteal(ts.i); if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); - return 0; + x87_ts ts; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + ts.s = (float) ST(0); + seteal(ts.i); + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst_32) : (x87_timings.fst_32 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst_32) : (x87_concurrency.fst_32 * cpu_multi)); + return 0; } #endif diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 3e09cac22..0ce89311c 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -1,939 +1,1046 @@ #ifdef FPU_8087 -static int opFI(uint32_t fetchdat) +static int +opFI(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxc &= ~0x80; - if (rmdat == 0xe1) - cpu_state.npxc |= 0x80; - wait(3, 0); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxc &= ~0x80; + if (rmdat == 0xe1) + cpu_state.npxc |= 0x80; + wait(3, 0); + return 0; } #else -static int opFSTSW_AX(uint32_t fetchdat) +static int +opFSTSW_AX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - AX = cpu_state.npxs; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + AX = cpu_state.npxs; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return 0; } #endif - -static int opFNOP(uint32_t fetchdat) +static int +opFNOP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); + return 0; } -static int opFCLEX(uint32_t fetchdat) +static int +opFCLEX(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= 0xff00; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= 0xff00; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fnop) : (x87_timings.fnop * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fnop) : (x87_concurrency.fnop * cpu_multi)); + return 0; } -static int opFINIT(uint32_t fetchdat) +static int +opFINIT(uint32_t fetchdat) { - uint64_t *p; - FP_ENTER(); - cpu_state.pc++; + uint64_t *p; + FP_ENTER(); + cpu_state.pc++; #ifdef FPU_8087 - cpu_state.npxc = 0x3FF; + cpu_state.npxc = 0x3FF; #else - cpu_state.npxc = 0x37F; + cpu_state.npxc = 0x37F; #endif - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - *p = 0; + *p = 0; #else - *p = 0x0303030303030303ll; + *p = 0x0303030303030303ll; #endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); - CPU_BLOCK_END(); - return 0; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.finit) : (x87_timings.finit * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.finit) : (x87_concurrency.finit * cpu_multi)); + CPU_BLOCK_END(); + return 0; } - -static int opFFREE(uint32_t fetchdat) +static int +opFFREE(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; + FP_ENTER(); + cpu_state.pc++; #ifdef USE_NEW_DYNAREC - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = TAG_EMPTY; #else - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; #endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); - return 0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); + return 0; } -static int opFFREEP(uint32_t fetchdat) +static int +opFFREEP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; if (cpu_state.abrt) return 1; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = 3; + if (cpu_state.abrt) + return 1; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ffree) : (x87_timings.ffree * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ffree) : (x87_concurrency.ffree * cpu_multi)); + return 0; } -static int opFST(uint32_t fetchdat) +static int +opFST(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); + return 0; } -static int opFSTP(uint32_t fetchdat) +static int +opFSTP(uint32_t fetchdat) { - FP_ENTER(); - cpu_state.pc++; - ST(fetchdat & 7) = ST(0); - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); - return 0; + FP_ENTER(); + cpu_state.pc++; + ST(fetchdat & 7) = ST(0); + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = cpu_state.tag[cpu_state.TOP & 7]; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fst) : (x87_timings.fst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fst) : (x87_concurrency.fst * cpu_multi)); + return 0; } - - - -static int FSTOR(void) +static int +FSTOR(void) { - uint64_t *p; - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 14; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - cpu_state.eaaddr += 28; - break; - } - x87_ld_frstor(0); cpu_state.eaaddr += 10; - x87_ld_frstor(1); cpu_state.eaaddr += 10; - x87_ld_frstor(2); cpu_state.eaaddr += 10; - x87_ld_frstor(3); cpu_state.eaaddr += 10; - x87_ld_frstor(4); cpu_state.eaaddr += 10; - x87_ld_frstor(5); cpu_state.eaaddr += 10; - x87_ld_frstor(6); cpu_state.eaaddr += 10; - x87_ld_frstor(7); + uint64_t *p; + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 2); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 14; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 4); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + cpu_state.eaaddr += 28; + break; + } + x87_ld_frstor(0); + cpu_state.eaaddr += 10; + x87_ld_frstor(1); + cpu_state.eaaddr += 10; + x87_ld_frstor(2); + cpu_state.eaaddr += 10; + x87_ld_frstor(3); + cpu_state.eaaddr += 10; + x87_ld_frstor(4); + cpu_state.eaaddr += 10; + x87_ld_frstor(5); + cpu_state.eaaddr += 10; + x87_ld_frstor(6); + cpu_state.eaaddr += 10; + x87_ld_frstor(7); - cpu_state.ismmx = 0; - /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times - something like this is needed*/ - p = (uint64_t *) cpu_state.tag; + cpu_state.ismmx = 0; + /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times + something like this is needed*/ + p = (uint64_t *) cpu_state.tag; #ifdef USE_NEW_DYNAREC - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && (*p == 0x0101010101010101ull)) + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && (*p == 0x0101010101010101ull)) #else - if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && - cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*p)) - #endif - cpu_state.ismmx = 1; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && !cpu_state.TOP && !(*p)) +#endif + cpu_state.ismmx = 1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); - return cpu_state.abrt; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frstor) : (x87_timings.frstor * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frstor) : (x87_concurrency.frstor * cpu_multi)); + return cpu_state.abrt; } -static int opFSTOR_a16(uint32_t fetchdat) +static int +opFSTOR_a16(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } #ifndef FPU_8087 -static int opFSTOR_a32(uint32_t fetchdat) +static int +opFSTOR_a32(uint32_t fetchdat) { - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FSTOR(); - return cpu_state.abrt; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FSTOR(); + return cpu_state.abrt; } #endif -static int FSAVE(void) +static int +FSAVE(void) { - uint64_t *p; + uint64_t *p; - FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - cpu_state.eaaddr+=14; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - cpu_state.eaaddr+=28; - if (cpu_state.ismmx) - { - x87_stmmx(cpu_state.MM[0]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[1]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[2]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[3]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[4]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[5]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[6]); cpu_state.eaaddr+=10; - x87_stmmx(cpu_state.MM[7]); - } - else - { - x87_st_fsave(0); cpu_state.eaaddr+=10; - x87_st_fsave(1); cpu_state.eaaddr+=10; - x87_st_fsave(2); cpu_state.eaaddr+=10; - x87_st_fsave(3); cpu_state.eaaddr+=10; - x87_st_fsave(4); cpu_state.eaaddr+=10; - x87_st_fsave(5); cpu_state.eaaddr+=10; - x87_st_fsave(6); cpu_state.eaaddr+=10; - x87_st_fsave(7); - } - break; + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + cpu_state.eaaddr += 14; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 8, x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_op_seg); + cpu_state.eaaddr += 14; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, (x87_op_off >> 16) << 12); + cpu_state.eaaddr += 28; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememl(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememl(easeg, cpu_state.eaaddr + 16, x87_pc_seg); + writememl(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, x87_op_seg); + cpu_state.eaaddr += 28; + if (cpu_state.ismmx) { + x87_stmmx(cpu_state.MM[0]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[1]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[2]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[3]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[4]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[5]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[6]); + cpu_state.eaaddr += 10; + x87_stmmx(cpu_state.MM[7]); + } else { + x87_st_fsave(0); + cpu_state.eaaddr += 10; + x87_st_fsave(1); + cpu_state.eaaddr += 10; + x87_st_fsave(2); + cpu_state.eaaddr += 10; + x87_st_fsave(3); + cpu_state.eaaddr += 10; + x87_st_fsave(4); + cpu_state.eaaddr += 10; + x87_st_fsave(5); + cpu_state.eaaddr += 10; + x87_st_fsave(6); + cpu_state.eaaddr += 10; + x87_st_fsave(7); + } + break; + } + + cpu_state.npxc = 0x37F; + codegen_set_rounding_mode(X87_ROUNDING_NEAREST); + cpu_state.npxs = 0; + p = (uint64_t *) cpu_state.tag; +#ifdef USE_NEW_DYNAREC + *p = 0; +#else + *p = 0x0303030303030303ll; +#endif + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); + return cpu_state.abrt; +} +static int +opFSAVE_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSAVE_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSAVE(); + return cpu_state.abrt; +} +#endif + +static int +opFSTSW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTSW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#endif + +static int +opFLD(uint32_t fetchdat) +{ + int old_tag; + uint64_t old_i64; + + FP_ENTER(); + cpu_state.pc++; + old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + x87_push(ST(fetchdat & 7)); + cpu_state.tag[cpu_state.TOP & 7] = old_tag; + cpu_state.MM[cpu_state.TOP & 7].q = old_i64; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); + return 0; +} + +static int +opFXCH(uint32_t fetchdat) +{ + double td; + uint8_t old_tag; + uint64_t old_i64; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = ST(fetchdat & 7); + ST(fetchdat & 7) = td; + old_tag = cpu_state.tag[cpu_state.TOP & 7]; + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; + cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; + old_i64 = cpu_state.MM[cpu_state.TOP & 7].q; + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; + cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; + + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); + return 0; +} + +static int +opFCHS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = -ST(0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); + return 0; +} + +static int +opFABS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = fabs(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); + return 0; +} + +static int +opFTST(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C2 | C3); + if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else if (ST(0) < 0.0) + cpu_state.npxs |= C0; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); + return 0; +} + +static int +opFXAM(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); +#ifdef USE_NEW_DYNAREC + if (cpu_state.tag[cpu_state.TOP & 7] == TAG_EMPTY) + cpu_state.npxs |= (C0 | C3); +#else + if (cpu_state.tag[cpu_state.TOP & 7] == 3) + cpu_state.npxs |= (C0 | C3); +#endif + else if (ST(0) == 0.0) + cpu_state.npxs |= C3; + else + cpu_state.npxs |= C2; + if (ST(0) < 0.0) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); + return 0; +} + +static int +opFLD1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.0); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); + return 0; +} + +static int +opFLDL2T(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.3219280948873623); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDL2E(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(1.4426950408889634); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDPI(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(3.141592653589793); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDEG2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.3010299956639812); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDLN2(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push_u64(0x3fe62e42fefa39f0ull); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); + return 0; +} + +static int +opFLDZ(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + x87_push(0.0); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); + return 0; +} + +static int +opF2XM1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = pow(2.0, ST(0)) - 1.0; + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); + return 0; +} + +static int +opFYL2X(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log(ST(0)) / log(2.0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); + return 0; +} + +static int +opFYL2XP1(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); + return 0; +} + +static int +opFPTAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = tan(ST(0)); + FP_TAG_VALID; + x87_push(1.0); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); + return 0; +} + +static int +opFPATAN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(1) = atan2(ST(1), ST(0)); + FP_TAG_VALID_N; + x87_pop(); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); + return 0; +} + +static int +opFDECSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP--; +#else + cpu_state.TOP = (cpu_state.TOP - 1) & 7; +#endif + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); + return 0; +} + +static int +opFINCSTP(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; +#ifdef USE_NEW_DYNAREC + cpu_state.TOP++; +#else + cpu_state.TOP = (cpu_state.TOP + 1) & 7; +#endif + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); + return 0; +} + +static int +opFPREM(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) (ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double) temp64); + FP_TAG_VALID; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + if (temp64 & 4) + cpu_state.npxs |= C0; + if (temp64 & 2) + cpu_state.npxs |= C3; + if (temp64 & 1) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +opFPREM1(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) (ST(0) / ST(1)); + ST(0) = ST(0) - (ST(1) * (double) temp64); + FP_TAG_VALID; + cpu_state.npxs &= ~(C0 | C1 | C2 | C3); + if (temp64 & 4) + cpu_state.npxs |= C0; + if (temp64 & 2) + cpu_state.npxs |= C3; + if (temp64 & 1) + cpu_state.npxs |= C1; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); + return 0; +} +#endif + +static int +opFSQRT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sqrt(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); + return 0; +} + +#ifndef FPU_8087 +static int +opFSINCOS(uint32_t fetchdat) +{ + double td; + FP_ENTER(); + cpu_state.pc++; + td = ST(0); + ST(0) = sin(td); + FP_TAG_VALID; + x87_push(cos(td)); + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); + return 0; +} +#endif + +static int +opFRNDINT(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = (double) x87_fround(ST(0)); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); + return 0; +} + +static int +opFSCALE(uint32_t fetchdat) +{ + int64_t temp64; + FP_ENTER(); + cpu_state.pc++; + temp64 = (int64_t) ST(1); + if (ST(0) != 0.0) + ST(0) = ST(0) * pow(2.0, (double) temp64); + FP_TAG_VALID; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); + return 0; +} + +#ifndef FPU_8087 +static int +opFSIN(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = sin(ST(0)); + FP_TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); + return 0; +} + +static int +opFCOS(uint32_t fetchdat) +{ + FP_ENTER(); + cpu_state.pc++; + ST(0) = cos(ST(0)); + FP_TAG_VALID; + cpu_state.npxs &= ~C2; + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); + return 0; +} +#endif + +static int +FLDENV(void) +{ + FP_ENTER(); + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + case 0x001: /*16-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 2); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 4)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + case 0x100: /*32-bit real mode*/ + case 0x101: /*32-bit protected mode*/ + cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr + 4); + x87_settag(readmemw(easeg, cpu_state.eaaddr + 8)); + cpu_state.TOP = (cpu_state.npxs >> 11) & 7; + break; + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); + return cpu_state.abrt; +} + +static int +opFLDENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFLDENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + FLDENV(); + return cpu_state.abrt; +} +#endif + +static int +opFLDCW_a16(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); + return 0; +} +#ifndef FPU_8087 +static int +opFLDCW_a32(uint32_t fetchdat) +{ + uint16_t tempw; + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_READ(cpu_state.ea_seg); + tempw = geteaw(); + if (cpu_state.abrt) + return 1; + cpu_state.npxc = tempw; + codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); + return 0; +} +#endif + +static int +FSTENV(void) +{ + FP_ENTER(); + cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); + + switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { + case 0x000: /*16-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + break; + case 0x001: /*16-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 2, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 4, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 6, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 8, x87_pc_seg); + writememw(easeg, cpu_state.eaaddr + 10, x87_op_off); + writememw(easeg, cpu_state.eaaddr + 12, x87_op_seg); + break; + case 0x100: /*32-bit real mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememw(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememw(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, (x87_op_off >> 16) << 12); + break; + case 0x101: /*32-bit protected mode*/ + writememw(easeg, cpu_state.eaaddr, cpu_state.npxc); + writememw(easeg, cpu_state.eaaddr + 4, cpu_state.npxs); + writememw(easeg, cpu_state.eaaddr + 8, x87_gettag()); + writememl(easeg, cpu_state.eaaddr + 12, x87_pc_off); + writememl(easeg, cpu_state.eaaddr + 16, x87_pc_seg); + writememl(easeg, cpu_state.eaaddr + 20, x87_op_off); + writememl(easeg, cpu_state.eaaddr + 24, x87_op_seg); + break; + } + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); + return cpu_state.abrt; +} + +static int +opFSTENV_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTENV_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + FSTENV(); + return cpu_state.abrt; +} +#endif + +static int +opFSTCW_a16(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_16(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); + return cpu_state.abrt; +} +#ifndef FPU_8087 +static int +opFSTCW_a32(uint32_t fetchdat) +{ + FP_ENTER(); + fetch_ea_32(fetchdat); + SEG_CHECK_WRITE(cpu_state.ea_seg); + seteaw(cpu_state.npxc); + CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); + CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); + return cpu_state.abrt; +} +#endif + +#ifndef FPU_8087 +# define opFCMOV(condition) \ + static int opFCMOV##condition(uint32_t fetchdat) \ + { \ + FP_ENTER(); \ + cpu_state.pc++; \ + if (cond_##condition) { \ + cpu_state.tag[cpu_state.TOP & 7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ + cpu_state.MM[cpu_state.TOP & 7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ + ST(0) = ST(fetchdat & 7); \ + } \ + CLOCK_CYCLES_FPU(4); \ + return 0; \ } - cpu_state.npxc = 0x37F; - codegen_set_rounding_mode(X87_ROUNDING_NEAREST); - cpu_state.npxs = 0; - p = (uint64_t *)cpu_state.tag; -#ifdef USE_NEW_DYNAREC - *p = 0; -#else - *p = 0x0303030303030303ll; -#endif - cpu_state.TOP = 0; - cpu_state.ismmx = 0; - - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsave) : (x87_timings.fsave * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsave) : (x87_concurrency.fsave * cpu_multi)); - return cpu_state.abrt; -} -static int opFSAVE_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSAVE_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSAVE(); - return cpu_state.abrt; -} -#endif - -static int opFSTSW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTSW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw((cpu_state.npxs & 0xC7FF) | ((cpu_state.TOP & 7) << 11)); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#endif - - -static int opFLD(uint32_t fetchdat) -{ - int old_tag; - uint64_t old_i64; - - FP_ENTER(); - cpu_state.pc++; - old_tag = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; - old_i64 = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - x87_push(ST(fetchdat&7)); - cpu_state.tag[cpu_state.TOP&7] = old_tag; - cpu_state.MM[cpu_state.TOP&7].q = old_i64; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld) : (x87_timings.fld * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld) : (x87_concurrency.fld * cpu_multi)); - return 0; -} - -static int opFXCH(uint32_t fetchdat) -{ - double td; - uint8_t old_tag; - uint64_t old_i64; - FP_ENTER(); - cpu_state.pc++; - td = ST(0); - ST(0) = ST(fetchdat&7); - ST(fetchdat&7) = td; - old_tag = cpu_state.tag[cpu_state.TOP&7]; - cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; - cpu_state.tag[(cpu_state.TOP + fetchdat) & 7] = old_tag; - old_i64 = cpu_state.MM[cpu_state.TOP&7].q; - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; - cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q = old_i64; - - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxch) : (x87_timings.fxch * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxch) : (x87_concurrency.fxch * cpu_multi)); - return 0; -} - -static int opFCHS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = -ST(0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fchs) : (x87_timings.fchs * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fchs) : (x87_concurrency.fchs * cpu_multi)); - return 0; -} - -static int opFABS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = fabs(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fabs) : (x87_timings.fabs * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fabs) : (x87_concurrency.fabs * cpu_multi)); - return 0; -} - -static int opFTST(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C2|C3); - if (ST(0) == 0.0) cpu_state.npxs |= C3; - else if (ST(0) < 0.0) cpu_state.npxs |= C0; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.ftst) : (x87_timings.ftst * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.ftst) : (x87_concurrency.ftst * cpu_multi)); - return 0; -} - -static int opFXAM(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - cpu_state.npxs &= ~(C0|C1|C2|C3); -#ifdef USE_NEW_DYNAREC - if (cpu_state.tag[cpu_state.TOP&7] == TAG_EMPTY) cpu_state.npxs |= (C0|C3); -#else - if (cpu_state.tag[cpu_state.TOP&7] == 3) cpu_state.npxs |= (C0|C3); -#endif - else if (ST(0) == 0.0) cpu_state.npxs |= C3; - else cpu_state.npxs |= C2; - if (ST(0) < 0.0) cpu_state.npxs |= C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fxam) : (x87_timings.fxam * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fxam) : (x87_concurrency.fxam * cpu_multi)); - return 0; -} - -static int opFLD1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(1.0); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); - return 0; -} - -static int opFLDL2T(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(3.3219280948873623); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDL2E(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(1.4426950408889634); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDPI(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(3.141592653589793); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDEG2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(0.3010299956639812); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDLN2(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push_u64(0x3fe62e42fefa39f0ull); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_const) : (x87_timings.fld_const * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_const) : (x87_concurrency.fld_const * cpu_multi)); - return 0; -} - -static int opFLDZ(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - x87_push(0.0); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fld_z1) : (x87_timings.fld_z1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fld_z1) : (x87_concurrency.fld_z1 * cpu_multi)); - return 0; -} - -static int opF2XM1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = pow(2.0, ST(0)) - 1.0; - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.f2xm1) : (x87_timings.f2xm1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.f2xm1) : (x87_concurrency.f2xm1 * cpu_multi)); - return 0; -} - -static int opFYL2X(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = ST(1) * (log(ST(0)) / log(2.0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2x) : (x87_timings.fyl2x * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2x) : (x87_concurrency.fyl2x * cpu_multi)); - return 0; -} - -static int opFYL2XP1(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = ST(1) * (log1p(ST(0)) / log(2.0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fyl2xp1) : (x87_timings.fyl2xp1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fyl2xp1) : (x87_concurrency.fyl2xp1 * cpu_multi)); - return 0; -} - -static int opFPTAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = tan(ST(0)); - FP_TAG_VALID; - x87_push(1.0); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fptan) : (x87_timings.fptan * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fptan) : (x87_concurrency.fptan * cpu_multi)); - return 0; -} - -static int opFPATAN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(1) = atan2(ST(1), ST(0)); - FP_TAG_VALID_N; - x87_pop(); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fpatan) : (x87_timings.fpatan * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fpatan) : (x87_concurrency.fpatan * cpu_multi)); - return 0; -} - -static int opFDECSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; -#ifdef USE_NEW_DYNAREC - cpu_state.TOP--; -#else - cpu_state.TOP = (cpu_state.TOP - 1) & 7; -#endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); - return 0; -} - -static int opFINCSTP(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; -#ifdef USE_NEW_DYNAREC - cpu_state.TOP++; -#else - cpu_state.TOP = (cpu_state.TOP + 1) & 7; -#endif - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fincdecstp) : (x87_timings.fincdecstp * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fincdecstp) : (x87_concurrency.fincdecstp * cpu_multi)); - return 0; -} - -static int opFPREM(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG_VALID; - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem) : (x87_timings.fprem * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem) : (x87_concurrency.fprem * cpu_multi)); - return 0; -} -#ifndef FPU_8087 -static int opFPREM1(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)(ST(0) / ST(1)); - ST(0) = ST(0) - (ST(1) * (double)temp64); - FP_TAG_VALID; - cpu_state.npxs &= ~(C0|C1|C2|C3); - if (temp64 & 4) cpu_state.npxs|=C0; - if (temp64 & 2) cpu_state.npxs|=C3; - if (temp64 & 1) cpu_state.npxs|=C1; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fprem1) : (x87_timings.fprem1 * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fprem1) : (x87_concurrency.fprem1 * cpu_multi)); - return 0; -} -#endif - -static int opFSQRT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = sqrt(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsqrt) : (x87_timings.fsqrt * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsqrt) : (x87_concurrency.fsqrt * cpu_multi)); - return 0; -} - -#ifndef FPU_8087 -static int opFSINCOS(uint32_t fetchdat) -{ - double td; - FP_ENTER(); - cpu_state.pc++; - td = ST(0); - ST(0) = sin(td); - FP_TAG_VALID; - x87_push(cos(td)); - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsincos) : (x87_timings.fsincos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsincos) : (x87_concurrency.fsincos * cpu_multi)); - return 0; -} -#endif - -static int opFRNDINT(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = (double)x87_fround(ST(0)); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.frndint) : (x87_timings.frndint * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.frndint) : (x87_concurrency.frndint * cpu_multi)); - return 0; -} - -static int opFSCALE(uint32_t fetchdat) -{ - int64_t temp64; - FP_ENTER(); - cpu_state.pc++; - temp64 = (int64_t)ST(1); - if(ST(0) != 0.0) - ST(0) = ST(0) * pow(2.0, (double)temp64); - FP_TAG_VALID; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fscale) : (x87_timings.fscale * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fscale) : (x87_concurrency.fscale * cpu_multi)); - return 0; -} - -#ifndef FPU_8087 -static int opFSIN(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = sin(ST(0)); - FP_TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); - return 0; -} - -static int opFCOS(uint32_t fetchdat) -{ - FP_ENTER(); - cpu_state.pc++; - ST(0) = cos(ST(0)); - FP_TAG_VALID; - cpu_state.npxs &= ~C2; - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fsin_cos) : (x87_timings.fsin_cos * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fsin_cos) : (x87_concurrency.fsin_cos * cpu_multi)); - return 0; -} -#endif - - -static int FLDENV(void) -{ - FP_ENTER(); - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - case 0x001: /*16-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+2); - x87_settag(readmemw(easeg, cpu_state.eaaddr+4)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - case 0x100: /*32-bit real mode*/ - case 0x101: /*32-bit protected mode*/ - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - cpu_state.npxs = readmemw(easeg, cpu_state.eaaddr+4); - x87_settag(readmemw(easeg, cpu_state.eaaddr+8)); - cpu_state.TOP = (cpu_state.npxs >> 11) & 7; - break; - } - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldenv) : (x87_timings.fldenv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldenv) : (x87_concurrency.fldenv * cpu_multi)); - return cpu_state.abrt; -} - -static int opFLDENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFLDENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - FLDENV(); - return cpu_state.abrt; -} -#endif - -static int opFLDCW_a16(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); - return 0; -} -#ifndef FPU_8087 -static int opFLDCW_a32(uint32_t fetchdat) -{ - uint16_t tempw; - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_READ(cpu_state.ea_seg); - tempw = geteaw(); - if (cpu_state.abrt) return 1; - cpu_state.npxc = tempw; - codegen_set_rounding_mode((cpu_state.npxc >> 10) & 3); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fldcw) : (x87_timings.fldcw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fldcw) : (x87_concurrency.fldcw * cpu_multi)); - return 0; -} -#endif - -static int FSTENV(void) -{ - FP_ENTER(); - cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11); - - switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) - { - case 0x000: /*16-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - break; - case 0x001: /*16-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+2,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+4,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+6,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+8,x87_pc_seg); - writememw(easeg,cpu_state.eaaddr+10,x87_op_off); - writememw(easeg,cpu_state.eaaddr+12,x87_op_seg); - break; - case 0x100: /*32-bit real mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememw(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememw(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,(x87_op_off>>16)<<12); - break; - case 0x101: /*32-bit protected mode*/ - writememw(easeg,cpu_state.eaaddr,cpu_state.npxc); - writememw(easeg,cpu_state.eaaddr+4,cpu_state.npxs); - writememw(easeg,cpu_state.eaaddr+8,x87_gettag()); - writememl(easeg,cpu_state.eaaddr+12,x87_pc_off); - writememl(easeg,cpu_state.eaaddr+16,x87_pc_seg); - writememl(easeg,cpu_state.eaaddr+20,x87_op_off); - writememl(easeg,cpu_state.eaaddr+24,x87_op_seg); - break; - } - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstenv) : (x87_timings.fstenv * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); - return cpu_state.abrt; -} - -static int opFSTENV_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTENV_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - FSTENV(); - return cpu_state.abrt; -} -#endif - -static int opFSTCW_a16(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_16(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.npxc); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstenv) : (x87_concurrency.fstenv * cpu_multi)); - return cpu_state.abrt; -} -#ifndef FPU_8087 -static int opFSTCW_a32(uint32_t fetchdat) -{ - FP_ENTER(); - fetch_ea_32(fetchdat); - SEG_CHECK_WRITE(cpu_state.ea_seg); - seteaw(cpu_state.npxc); - CLOCK_CYCLES_FPU((fpu_type >= FPU_487SX) ? (x87_timings.fstcw_sw) : (x87_timings.fstcw_sw * cpu_multi)); - CONCURRENCY_CYCLES((fpu_type >= FPU_487SX) ? (x87_concurrency.fstcw_sw) : (x87_concurrency.fstcw_sw * cpu_multi)); - return cpu_state.abrt; -} -#endif - -#ifndef FPU_8087 -#define opFCMOV(condition) \ - static int opFCMOV ## condition(uint32_t fetchdat) \ - { \ - FP_ENTER(); \ - cpu_state.pc++; \ - if (cond_ ## condition) \ - { \ - cpu_state.tag[cpu_state.TOP&7] = cpu_state.tag[(cpu_state.TOP + fetchdat) & 7]; \ - cpu_state.MM[cpu_state.TOP&7].q = cpu_state.MM[(cpu_state.TOP + fetchdat) & 7].q; \ - ST(0) = ST(fetchdat & 7); \ - } \ - CLOCK_CYCLES_FPU(4); \ - return 0; \ - } - -#define cond_U ( PF_SET()) -#define cond_NU (!PF_SET()) +# define cond_U (PF_SET()) +# define cond_NU (!PF_SET()) opFCMOV(B) opFCMOV(E) diff --git a/src/cpu/x87_timings.c b/src/cpu/x87_timings.c index 70ec4b95e..a23e195d2 100644 --- a/src/cpu/x87_timings.c +++ b/src/cpu/x87_timings.c @@ -85,80 +85,79 @@ const x87_timings_t x87_timings_8087 = { .fyl2xp1 = (700 + 1000) / 2 }; -const x87_timings_t x87_timings_80187 = -{ - .f2xm1 = (310 + 630) / 2, - .fabs = (10 + 17) / 2, - .fadd = (70 + 100) / 2, - .fadd_32 = (90 + 120) / 2, - .fadd_64 = (95 + 125) / 2, - .fbld = (290 + 310) / 2, - .fbstp = (520 + 540) / 2, - .fchs = (10 + 17) / 2, - .fclex = (2 + 8) / 2, - .fcom = (40 + 50) / 2, - .fcom_32 = (60 + 70) / 2, - .fcom_64 = (65 + 75) / 2, - .fcos = 0, /*387+*/ - .fincdecstp = (6 + 12) / 2, - .fdisi_eni = (6 + 12) / 2, - .fdiv = (193 + 203) / 2, - .fdiv_32 = (215 + 225) / 2, - .fdiv_64 = (220 + 230) / 2, - .ffree = (9 + 16) / 2, - .fadd_i16 = (102 + 137) / 2, - .fadd_i32 = (108 + 143) / 2, - .fcom_i16 = (72 + 86) / 2, - .fcom_i32 = (78 + 91) / 2, - .fdiv_i16 = (224 + 238) / 2, - .fdiv_i32 = (230 + 243) / 2, - .fild_16 = (46 + 54) / 2, - .fild_32 = (50 + 60) / 2, - .fild_64 = (60 + 68) / 2, - .fmul_i16 = (124 + 138) / 2, - .fmul_i32 = (130 + 144) / 2, - .finit = (2 + 8) / 2, - .fist_16 = (80 + 90) / 2, - .fist_32 = (82 + 92) / 2, - .fist_64 = (94 + 105) / 2, - .fld = (17 + 22) / 2, - .fld_32 = (38 + 56) / 2, - .fld_64 = (40 + 60) / 2, - .fld_80 = (53 + 65) / 2, - .fld_z1 = (11 + 21) / 2, - .fld_const = (15 + 24) / 2, - .fldcw = (7 + 14) / 2, - .fldenv = (35 + 45) / 2, - .fmul = (90 + 145) / 2, - .fmul_32 = (110 + 125) / 2, - .fmul_64 = (154 + 168) / 2, - .fnop = (10 + 16) / 2, - .fpatan = (250 + 800) / 2, - .fprem = (15 + 190) / 2, - .fprem1 = 0, /*387+*/ - .fptan = (30 + 540) / 2, - .frndint = (16 + 50) / 2, - .frstor = (197 + 207) / 2, - .fsave = (197 + 207) / 2, - .fscale = (32 + 38) / 2, - .fsetpm = 0, /*287+*/ - .fsin_cos = 0, /*387+*/ - .fsincos = 0, /*387+*/ - .fsqrt = (180 + 186) / 2, - .fst = (15 + 22) / 2, - .fst_32 = (84 + 90) / 2, - .fst_64 = (96 + 104) / 2, - .fst_80 = (52 + 58) / 2, - .fstcw_sw = (12 + 18) / 2, - .fstenv = (40 + 50) / 2, - .ftst = (38 + 48) / 2, - .fucom = 0, /*387+*/ - .fwait = 4, - .fxam = (12 + 23) / 2, - .fxch = (10 + 15) / 2, - .fxtract = (27 + 55) / 2, - .fyl2x = (900 + 1100) / 2, - .fyl2xp1 = (700 + 1000) / 2 +const x87_timings_t x87_timings_80187 = { + .f2xm1 = (310 + 630) / 2, + .fabs = (10 + 17) / 2, + .fadd = (70 + 100) / 2, + .fadd_32 = (90 + 120) / 2, + .fadd_64 = (95 + 125) / 2, + .fbld = (290 + 310) / 2, + .fbstp = (520 + 540) / 2, + .fchs = (10 + 17) / 2, + .fclex = (2 + 8) / 2, + .fcom = (40 + 50) / 2, + .fcom_32 = (60 + 70) / 2, + .fcom_64 = (65 + 75) / 2, + .fcos = 0, /*387+*/ + .fincdecstp = (6 + 12) / 2, + .fdisi_eni = (6 + 12) / 2, + .fdiv = (193 + 203) / 2, + .fdiv_32 = (215 + 225) / 2, + .fdiv_64 = (220 + 230) / 2, + .ffree = (9 + 16) / 2, + .fadd_i16 = (102 + 137) / 2, + .fadd_i32 = (108 + 143) / 2, + .fcom_i16 = (72 + 86) / 2, + .fcom_i32 = (78 + 91) / 2, + .fdiv_i16 = (224 + 238) / 2, + .fdiv_i32 = (230 + 243) / 2, + .fild_16 = (46 + 54) / 2, + .fild_32 = (50 + 60) / 2, + .fild_64 = (60 + 68) / 2, + .fmul_i16 = (124 + 138) / 2, + .fmul_i32 = (130 + 144) / 2, + .finit = (2 + 8) / 2, + .fist_16 = (80 + 90) / 2, + .fist_32 = (82 + 92) / 2, + .fist_64 = (94 + 105) / 2, + .fld = (17 + 22) / 2, + .fld_32 = (38 + 56) / 2, + .fld_64 = (40 + 60) / 2, + .fld_80 = (53 + 65) / 2, + .fld_z1 = (11 + 21) / 2, + .fld_const = (15 + 24) / 2, + .fldcw = (7 + 14) / 2, + .fldenv = (35 + 45) / 2, + .fmul = (90 + 145) / 2, + .fmul_32 = (110 + 125) / 2, + .fmul_64 = (154 + 168) / 2, + .fnop = (10 + 16) / 2, + .fpatan = (250 + 800) / 2, + .fprem = (15 + 190) / 2, + .fprem1 = 0, /*387+*/ + .fptan = (30 + 540) / 2, + .frndint = (16 + 50) / 2, + .frstor = (197 + 207) / 2, + .fsave = (197 + 207) / 2, + .fscale = (32 + 38) / 2, + .fsetpm = 0, /*287+*/ + .fsin_cos = 0, /*387+*/ + .fsincos = 0, /*387+*/ + .fsqrt = (180 + 186) / 2, + .fst = (15 + 22) / 2, + .fst_32 = (84 + 90) / 2, + .fst_64 = (96 + 104) / 2, + .fst_80 = (52 + 58) / 2, + .fstcw_sw = (12 + 18) / 2, + .fstenv = (40 + 50) / 2, + .ftst = (38 + 48) / 2, + .fucom = 0, /*387+*/ + .fwait = 4, + .fxam = (12 + 23) / 2, + .fxch = (10 + 15) / 2, + .fxtract = (27 + 55) / 2, + .fyl2x = (900 + 1100) / 2, + .fyl2xp1 = (700 + 1000) / 2 }; /*Mostly the same as 8087*/ From 35fea100dba886a1a3a3463a306d2e9d43175c28 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 19 Nov 2022 10:43:42 -0500 Subject: [PATCH 4/6] clang-format markers --- src/codegen/codegen_ops.c | 24 ++++++ src/codegen/codegen_ops_jump.h | 2 + src/codegen/codegen_ops_mov.h | 2 + src/codegen_new/codegen_ops.c | 22 +++++ src/codegen_new/codegen_ops_mmx_arith.c | 2 + src/codegen_new/codegen_ops_mmx_cmp.c | 2 + src/codegen_new/codegen_ops_mmx_pack.c | 2 + src/cpu/386_ops.h | 46 ++++++++++ src/cpu/cpu_table.c | 2 + src/cpu/x86_ops_3dnow.h | 4 + src/cpu/x86_ops_jump.h | 3 + src/cpu/x86_ops_mov.h | 2 + src/cpu/x86_ops_mov_seg.h | 2 + src/cpu/x86_ops_prefix.h | 2 + src/cpu/x86_ops_set.h | 2 + src/cpu/x86_ops_shift.h | 2 + src/cpu/x86_ops_xchg.h | 2 + src/cpu/x87_ops.h | 106 ++++++++++++++++++++++++ src/cpu/x87_ops_misc.h | 2 + 19 files changed, 231 insertions(+) diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index a81e0c6a2..0ae102d24 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -34,6 +34,7 @@ RecompOpFn recomp_opcodes[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, @@ -77,10 +78,12 @@ RecompOpFn recomp_opcodes[512] = /*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32 +// clang-format on }; RecompOpFn recomp_opcodes_0f[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -124,11 +127,13 @@ RecompOpFn recomp_opcodes_0f[512] = /*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_d8[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, @@ -172,10 +177,12 @@ RecompOpFn recomp_opcodes_d8[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, +// clang-format on }; RecompOpFn recomp_opcodes_d9[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -219,10 +226,12 @@ RecompOpFn recomp_opcodes_d9[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_da[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, @@ -266,10 +275,12 @@ RecompOpFn recomp_opcodes_da[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_db[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -313,10 +324,12 @@ RecompOpFn recomp_opcodes_db[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_dc[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, @@ -360,10 +373,12 @@ RecompOpFn recomp_opcodes_dc[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, +// clang-format on }; RecompOpFn recomp_opcodes_dd[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -407,10 +422,12 @@ RecompOpFn recomp_opcodes_dd[512] = /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_de[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, @@ -454,10 +471,12 @@ RecompOpFn recomp_opcodes_de[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, +// clang-format on }; RecompOpFn recomp_opcodes_df[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -501,10 +520,12 @@ RecompOpFn recomp_opcodes_df[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_REPE[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -548,10 +569,12 @@ RecompOpFn recomp_opcodes_REPE[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_REPNE[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -595,4 +618,5 @@ RecompOpFn recomp_opcodes_REPNE[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; diff --git a/src/codegen/codegen_ops_jump.h b/src/codegen/codegen_ops_jump.h index 54e51f150..274eef24d 100644 --- a/src/codegen/codegen_ops_jump.h +++ b/src/codegen/codegen_ops_jump.h @@ -252,6 +252,7 @@ static uint32_t rop ## name ## _l(uint8_t opcode, \ return op_pc+4; \ } +// clang-format off ropBRANCH(JB, BRANCH_COND_B, 0) ropBRANCH(JNB, BRANCH_COND_B, 1) ropBRANCH(JE, BRANCH_COND_E, 0) @@ -268,3 +269,4 @@ ropBRANCH(JLE, BRANCH_COND_LE, 0) ropBRANCH(JNLE, BRANCH_COND_LE, 1) ropBRANCH(JBE, BRANCH_COND_BE, 0) ropBRANCH(JNBE, BRANCH_COND_BE, 1) +// clang-format on diff --git a/src/codegen/codegen_ops_mov.h b/src/codegen/codegen_ops_mov.h index f5e61eb60..04c4bf2bc 100644 --- a/src/codegen/codegen_ops_mov.h +++ b/src/codegen/codegen_ops_mov.h @@ -616,8 +616,10 @@ ropMOV_seg_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, return op_pc + 1; \ } +// clang-format off ropLseg(DS, cpu_state.seg_ds) ropLseg(ES, cpu_state.seg_es) ropLseg(FS, cpu_state.seg_fs) ropLseg(GS, cpu_state.seg_gs) ropLseg(SS, cpu_state.seg_ss) +// clang-format on diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 1e7183fff..2ac4a83d6 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -28,6 +28,7 @@ RecompOpFn recomp_opcodes[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, @@ -71,11 +72,13 @@ RecompOpFn recomp_opcodes[512] = /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_32 +// clang-format on }; RecompOpFn recomp_opcodes_0f[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -141,10 +144,12 @@ RecompOpFn recomp_opcodes_0f[512] = /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif +// clang-format on }; RecompOpFn recomp_opcodes_3DNOW[256] = { +// clang-format off #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 0 #else @@ -169,10 +174,12 @@ RecompOpFn recomp_opcodes_3DNOW[256] = /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, #endif +// clang-format on }; RecompOpFn recomp_opcodes_d8[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, @@ -216,10 +223,12 @@ RecompOpFn recomp_opcodes_d8[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, +// clang-format on }; RecompOpFn recomp_opcodes_d9[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -263,10 +272,12 @@ RecompOpFn recomp_opcodes_d9[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_da[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, @@ -310,10 +321,12 @@ RecompOpFn recomp_opcodes_da[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFUCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_db[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -357,10 +370,12 @@ RecompOpFn recomp_opcodes_db[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_dc[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, @@ -404,10 +419,12 @@ RecompOpFn recomp_opcodes_dc[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, +// clang-format on }; RecompOpFn recomp_opcodes_dd[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -451,10 +468,12 @@ RecompOpFn recomp_opcodes_dd[512] = /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; RecompOpFn recomp_opcodes_de[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, @@ -498,10 +517,12 @@ RecompOpFn recomp_opcodes_de[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, +// clang-format on }; RecompOpFn recomp_opcodes_df[512] = { +// clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -545,4 +566,5 @@ RecompOpFn recomp_opcodes_df[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +// clang-format on }; diff --git a/src/codegen_new/codegen_ops_mmx_arith.c b/src/codegen_new/codegen_ops_mmx_arith.c index 67e73883e..b352c402a 100644 --- a/src/codegen_new/codegen_ops_mmx_arith.c +++ b/src/codegen_new/codegen_ops_mmx_arith.c @@ -36,6 +36,7 @@ return op_pc + 1; \ } +// clang-format off ropParith(PADDB) ropParith(PADDW) ropParith(PADDD) @@ -55,3 +56,4 @@ ropParith(PSUBUSW) ropParith(PMADDWD) ropParith(PMULHW) ropParith(PMULLW) +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_cmp.c b/src/codegen_new/codegen_ops_mmx_cmp.c index 6e5010446..c8d4909f9 100644 --- a/src/codegen_new/codegen_ops_mmx_cmp.c +++ b/src/codegen_new/codegen_ops_mmx_cmp.c @@ -36,9 +36,11 @@ return op_pc + 1; \ } +// clang-format off ropPcmp(PCMPEQB) ropPcmp(PCMPEQW) ropPcmp(PCMPEQD) ropPcmp(PCMPGTB) ropPcmp(PCMPGTW) ropPcmp(PCMPGTD) +// clang-format on diff --git a/src/codegen_new/codegen_ops_mmx_pack.c b/src/codegen_new/codegen_ops_mmx_pack.c index 700cb7fbf..99016352e 100644 --- a/src/codegen_new/codegen_ops_mmx_pack.c +++ b/src/codegen_new/codegen_ops_mmx_pack.c @@ -36,6 +36,7 @@ return op_pc + 1; \ } +// clang-format off ropPpack(PACKSSWB) ropPpack(PACKSSDW) ropPpack(PACKUSWB) @@ -45,3 +46,4 @@ ropPpack(PUNPCKLDQ) ropPpack(PUNPCKHBW) ropPpack(PUNPCKHWD) ropPpack(PUNPCKHDQ) +// clang-format on diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index cad5a7b05..48b3a0c18 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -378,6 +378,7 @@ op0F_l_a32(uint32_t fetchdat) const OpFn OP_TABLE(186_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -465,10 +466,12 @@ const OpFn OP_TABLE(186_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(286_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -556,10 +559,12 @@ const OpFn OP_TABLE(286_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(386_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -647,10 +652,12 @@ const OpFn OP_TABLE(386_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(486_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -738,10 +745,12 @@ const OpFn OP_TABLE(486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(c486_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -829,10 +838,12 @@ const OpFn OP_TABLE(c486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(stpc_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -920,10 +931,12 @@ const OpFn OP_TABLE(stpc_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(ibm486_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1011,10 +1024,12 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(winchip_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1102,10 +1117,12 @@ const OpFn OP_TABLE(winchip_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(winchip2_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, @@ -1193,10 +1210,12 @@ const OpFn OP_TABLE(winchip2_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(pentium_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1284,11 +1303,13 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) const OpFn OP_TABLE(c6x86_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1376,11 +1397,13 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; #endif const OpFn OP_TABLE(pentiummmx_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1468,10 +1491,12 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(k6_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1559,10 +1584,12 @@ const OpFn OP_TABLE(k6_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(k62_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, @@ -1650,11 +1677,13 @@ const OpFn OP_TABLE(k62_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) const OpFn OP_TABLE(c6x86mx_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1742,11 +1771,13 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; #endif const OpFn OP_TABLE(pentiumpro_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -1834,10 +1865,12 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(pentium2_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -1925,10 +1958,12 @@ const OpFn OP_TABLE(pentium2_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(pentium2d_0f)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -2016,10 +2051,12 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(186)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2107,10 +2144,12 @@ const OpFn OP_TABLE(186)[1024] = /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, /*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +// clang-format on }; const OpFn OP_TABLE(286)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2198,10 +2237,12 @@ const OpFn OP_TABLE(286)[1024] = /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, /*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +// clang-format on }; const OpFn OP_TABLE(386)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2289,10 +2330,12 @@ const OpFn OP_TABLE(386)[1024] = /*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, /*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, /*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, +// clang-format on }; const OpFn OP_TABLE(REPE)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2380,10 +2423,12 @@ const OpFn OP_TABLE(REPE)[1024] = /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// clang-format on }; const OpFn OP_TABLE(REPNE)[1024] = { +// clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2471,4 +2516,5 @@ const OpFn OP_TABLE(REPNE)[1024] = /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// clang-format on }; diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 41c479290..6d2b860de 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -77,6 +77,7 @@ FPU fpus_internal[] = const cpu_family_t cpu_families[] = { +// clang-format off { .package = CPU_PKG_8088, .manufacturer = "Intel", @@ -1146,6 +1147,7 @@ const cpu_family_t cpu_families[] = { }, { .package = 0, } +// clang-format on }; /* Legacy CPU tables for backwards compatibility. */ diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index ca1f9c80a..06b48552d 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -380,6 +380,7 @@ opPMULHRW(uint32_t fetchdat) const OpFn OP_TABLE(3DNOW)[256] = { +// clang-format off /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, @@ -400,10 +401,12 @@ const OpFn OP_TABLE(3DNOW)[256] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; const OpFn OP_TABLE(3DNOWE)[256] = { +// clang-format off /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FW, opPI2FD, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2IW, opPF2ID, ILLEGAL, ILLEGAL, @@ -424,6 +427,7 @@ const OpFn OP_TABLE(3DNOWE)[256] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +// clang-format on }; static int diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index 2a338afdc..f9093084c 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -69,6 +69,7 @@ return 0; \ } +// clang-format off opJ(O) opJ(NO) opJ(B) @@ -85,6 +86,8 @@ opJ(L) opJ(NL) opJ(LE) opJ(NLE) +// clang-format on + static int opLOOPNE_w(uint32_t fetchdat) { diff --git a/src/cpu/x86_ops_mov.h b/src/cpu/x86_ops_mov.h index 33a8a44c0..063a33516 100644 --- a/src/cpu/x86_ops_mov.h +++ b/src/cpu/x86_ops_mov.h @@ -847,6 +847,7 @@ opMOV_r_l_a32(uint32_t fetchdat) return 0; \ } +// clang-format off opCMOV(O) opCMOV(NO) opCMOV(B) @@ -863,3 +864,4 @@ opCMOV(L) opCMOV(NL) opCMOV(LE) opCMOV(NLE) +// clang-format on diff --git a/src/cpu/x86_ops_mov_seg.h b/src/cpu/x86_ops_mov_seg.h index be8acb618..c6bfd9933 100644 --- a/src/cpu/x86_ops_mov_seg.h +++ b/src/cpu/x86_ops_mov_seg.h @@ -528,6 +528,8 @@ opLSS_l_a32(uint32_t fetchdat) return 0; \ } +// clang-format off opLsel(ES, cpu_state.seg_es) opLsel(FS, cpu_state.seg_fs) opLsel(GS, cpu_state.seg_gs) +// clang-format on diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index 4d4adb77d..5edb3dbea 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -67,6 +67,7 @@ return normal_opcode_table[(fetchdat & 0xff) | 0x300](fetchdat >> 8); \ } +// clang-format off op_seg(CS, cpu_state.seg_cs, x86_opcodes, x86_opcodes) op_seg(DS, cpu_state.seg_ds, x86_opcodes, x86_opcodes) op_seg(ES, cpu_state.seg_es, x86_opcodes, x86_opcodes) @@ -87,6 +88,7 @@ op_seg(ES_REPNE, cpu_state.seg_es, x86_opcodes_REPNE, x86_opcodes) op_seg(FS_REPNE, cpu_state.seg_fs, x86_opcodes_REPNE, x86_opcodes) op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) +// clang-format on static int op_66(uint32_t fetchdat) /*Data size select*/ { diff --git a/src/cpu/x86_ops_set.h b/src/cpu/x86_ops_set.h index 4d2a98bcb..30c076a6e 100644 --- a/src/cpu/x86_ops_set.h +++ b/src/cpu/x86_ops_set.h @@ -19,6 +19,7 @@ return cpu_state.abrt; \ } +// clang-format off opSET(O) opSET(NO) opSET(B) @@ -35,3 +36,4 @@ opSET(L) opSET(NL) opSET(LE) opSET(NLE) +// clang-format on diff --git a/src/cpu/x86_ops_shift.h b/src/cpu/x86_ops_shift.h index bba8e24f7..9c11a32f0 100644 --- a/src/cpu/x86_ops_shift.h +++ b/src/cpu/x86_ops_shift.h @@ -1048,7 +1048,9 @@ opD3_l_a32(uint32_t fetchdat) return 0; \ } +// clang-format off opSHxD(SHLD_w) opSHxD(SHLD_l) opSHxD(SHRD_w) opSHxD(SHRD_l) +// clang-format on diff --git a/src/cpu/x86_ops_xchg.h b/src/cpu/x86_ops_xchg.h index c572608eb..c5ce08999 100644 --- a/src/cpu/x86_ops_xchg.h +++ b/src/cpu/x86_ops_xchg.h @@ -266,6 +266,7 @@ opXCHG_EAX_ESP(uint32_t fetchdat) return 0; \ } +// clang-format off opBSWAP(EAX) opBSWAP(EBX) opBSWAP(ECX) @@ -274,3 +275,4 @@ opBSWAP(ESI) opBSWAP(EDI) opBSWAP(EBP) opBSWAP(ESP) +// clang-format on diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index cb7a35323..e8573bfa6 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -528,14 +528,17 @@ FPU_ILLEGAL_a32(uint32_t fetchdat) #ifdef FPU_8087 const OpFn OP_TABLE(fpu_8087_d8)[32] = { +// clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +// clang-format on }; const OpFn OP_TABLE(fpu_8087_d9)[256] = { +// clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -571,10 +574,12 @@ const OpFn OP_TABLE(fpu_8087_d9)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 +// clang-format on }; const OpFn OP_TABLE(fpu_8087_da)[256] = { +// clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -610,10 +615,12 @@ const OpFn OP_TABLE(fpu_8087_da)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; const OpFn OP_TABLE(fpu_8087_db)[256] = { +// clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -649,18 +656,22 @@ const OpFn OP_TABLE(fpu_8087_db)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; const OpFn OP_TABLE(fpu_8087_dc)[32] = { +// clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +// clang-format on }; const OpFn OP_TABLE(fpu_8087_dd)[256] = { +// clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -696,10 +707,12 @@ const OpFn OP_TABLE(fpu_8087_dd)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; const OpFn OP_TABLE(fpu_8087_de)[256] = { +// clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -735,10 +748,12 @@ const OpFn OP_TABLE(fpu_8087_de)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +// clang-format on }; const OpFn OP_TABLE(fpu_8087_df)[256] = { +// clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -774,27 +789,34 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; #else # define ILLEGAL_a32 FPU_ILLEGAL_a32 const OpFn OP_TABLE(fpu_d8_a16)[32] = { +// clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +// clang-format on }; + const OpFn OP_TABLE(fpu_d8_a32)[32] = { +// clang-format off opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR +// clang-format on }; const OpFn OP_TABLE(fpu_287_d9_a16)[256] = { +// clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -830,10 +852,12 @@ const OpFn OP_TABLE(fpu_287_d9_a16)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +// clang-format on }; const OpFn OP_TABLE(fpu_287_d9_a32)[256] = { +// clang-format off opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, @@ -869,10 +893,12 @@ const OpFn OP_TABLE(fpu_287_d9_a32)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +// clang-format on }; const OpFn OP_TABLE(fpu_d9_a16)[256] = { +// clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -908,10 +934,12 @@ const OpFn OP_TABLE(fpu_d9_a16)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +// clang-format on }; const OpFn OP_TABLE(fpu_d9_a32)[256] = { +// clang-format off opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, @@ -947,10 +975,12 @@ const OpFn OP_TABLE(fpu_d9_a32)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +// clang-format on }; const OpFn OP_TABLE(fpu_287_da_a16)[256] = { +// clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -986,9 +1016,12 @@ const OpFn OP_TABLE(fpu_287_da_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_287_da_a32)[256] = { +// clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1024,10 +1057,12 @@ const OpFn OP_TABLE(fpu_287_da_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_da_a16)[256] = { +// clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1063,9 +1098,12 @@ const OpFn OP_TABLE(fpu_da_a16)[256] = ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_da_a32)[256] = { +// clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1101,10 +1139,12 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_686_da_a16)[256] = { +// clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1140,9 +1180,12 @@ const OpFn OP_TABLE(fpu_686_da_a16)[256] = ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_686_da_a32)[256] = { +// clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1178,10 +1221,12 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] = ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_287_db_a16)[256] = { +// clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1217,9 +1262,12 @@ const OpFn OP_TABLE(fpu_287_db_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_287_db_a32)[256] = { +// clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1255,10 +1303,12 @@ const OpFn OP_TABLE(fpu_287_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_db_a16)[256] = { +// clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1294,9 +1344,12 @@ const OpFn OP_TABLE(fpu_db_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_db_a32)[256] = { +// clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1332,10 +1385,12 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_686_db_a16)[256] = { +// clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1371,9 +1426,11 @@ const OpFn OP_TABLE(fpu_686_db_a16)[256] = opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; const OpFn OP_TABLE(fpu_686_db_a32)[256] = { +// clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1409,40 +1466,52 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] = opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_287_dc_a16)[32] = { +// clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +// clang-format on }; + const OpFn OP_TABLE(fpu_287_dc_a32)[32] = { +// clang-format off opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +// clang-format on }; const OpFn OP_TABLE(fpu_dc_a16)[32] = { +// clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +// clang-format on }; + const OpFn OP_TABLE(fpu_dc_a32)[32] = { +// clang-format off opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +// clang-format on }; const OpFn OP_TABLE(fpu_287_dd_a16)[256] = { +// clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -1478,9 +1547,12 @@ const OpFn OP_TABLE(fpu_287_dd_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_287_dd_a32)[256] = { +// clang-format off opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, @@ -1516,10 +1588,12 @@ const OpFn OP_TABLE(fpu_287_dd_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_dd_a16)[256] = { +// clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -1555,9 +1629,12 @@ const OpFn OP_TABLE(fpu_dd_a16)[256] = opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_dd_a32)[256] = { +// clang-format off opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, @@ -1593,10 +1670,12 @@ const OpFn OP_TABLE(fpu_dd_a32)[256] = opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_287_de_a16)[256] = { +// clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -1632,10 +1711,12 @@ const OpFn OP_TABLE(fpu_287_de_a16)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +// clang-format on }; const OpFn OP_TABLE(fpu_287_de_a32)[256] = { +// clang-format off opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, @@ -1671,10 +1752,12 @@ const OpFn OP_TABLE(fpu_287_de_a32)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +// clang-format on }; const OpFn OP_TABLE(fpu_de_a16)[256] = { +// clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -1710,10 +1793,12 @@ const OpFn OP_TABLE(fpu_de_a16)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +// clang-format on }; const OpFn OP_TABLE(fpu_de_a32)[256] = { +// clang-format off opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, @@ -1749,10 +1834,12 @@ const OpFn OP_TABLE(fpu_de_a32)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +// clang-format on }; const OpFn OP_TABLE(fpu_287_df_a16)[256] = { +// clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1788,9 +1875,12 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_287_df_a32)[256] = { +// clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1826,10 +1916,12 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_df_a16)[256] = { +// clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1865,9 +1957,12 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_df_a32)[256] = { +// clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1903,10 +1998,12 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(fpu_686_df_a16)[256] = { +// clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1942,9 +2039,12 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, +// clang-format on }; + const OpFn OP_TABLE(fpu_686_df_a32)[256] = { +// clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1980,10 +2080,12 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, +// clang-format on }; const OpFn OP_TABLE(nofpu_a16)[256] = { +// clang-format off op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, @@ -2019,9 +2121,12 @@ const OpFn OP_TABLE(nofpu_a16)[256] = op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, +// clang-format on }; + const OpFn OP_TABLE(nofpu_a32)[256] = { +// clang-format off op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, @@ -2057,6 +2162,7 @@ const OpFn OP_TABLE(nofpu_a32)[256] = op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, +// clang-format on }; #endif diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 0ce89311c..091d7cc31 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -1042,6 +1042,7 @@ opFSTCW_a32(uint32_t fetchdat) # define cond_U (PF_SET()) # define cond_NU (!PF_SET()) +// clang-format off opFCMOV(B) opFCMOV(E) opFCMOV(BE) @@ -1050,4 +1051,5 @@ opFCMOV(NB) opFCMOV(NE) opFCMOV(NBE) opFCMOV(NU) +// clang-format on #endif From d802ec3485f00049dd91d72a404780c7925d67a6 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 19 Nov 2022 11:23:04 -0500 Subject: [PATCH 5/6] more clang-formatting in cpu --- src/cpu/386_ops.h | 161 ++-- src/cpu/cpu_table.c | 1671 +++++++++++++++++++------------------- src/cpu/x86_ops_3dnow.h | 14 +- src/cpu/x86_ops_jump.h | 3 +- src/cpu/x86_ops_prefix.h | 2 +- src/cpu/x86_ops_stack.h | 44 +- src/cpu/x87_ops.h | 322 ++++---- 7 files changed, 1068 insertions(+), 1149 deletions(-) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index 48b3a0c18..ec46ba0ae 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -376,9 +376,8 @@ op0F_l_a32(uint32_t fetchdat) return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } -const OpFn OP_TABLE(186_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(186_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -466,12 +465,11 @@ const OpFn OP_TABLE(186_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(286_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(286_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_286, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opLOADALL, opCLTS, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -559,12 +557,11 @@ const OpFn OP_TABLE(286_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(386_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(386_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -652,12 +649,11 @@ const OpFn OP_TABLE(386_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(486_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(486_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -745,12 +741,11 @@ const OpFn OP_TABLE(486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(c486_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(c486_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -838,12 +833,11 @@ const OpFn OP_TABLE(c486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(stpc_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(stpc_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -931,12 +925,11 @@ const OpFn OP_TABLE(stpc_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(ibm486_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(ibm486_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, opLOADALL386, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1024,12 +1017,11 @@ const OpFn OP_TABLE(ibm486_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(winchip_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(winchip_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1117,12 +1109,11 @@ const OpFn OP_TABLE(winchip_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(winchip2_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(winchip2_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, @@ -1210,12 +1201,11 @@ const OpFn OP_TABLE(winchip2_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(pentium_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(pentium_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1303,13 +1293,12 @@ const OpFn OP_TABLE(pentium_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) -const OpFn OP_TABLE(c6x86_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(c6x86_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1397,13 +1386,12 @@ const OpFn OP_TABLE(c6x86_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; #endif -const OpFn OP_TABLE(pentiummmx_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(pentiummmx_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1491,12 +1479,11 @@ const OpFn OP_TABLE(pentiummmx_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(k6_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(k6_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1584,12 +1571,11 @@ const OpFn OP_TABLE(k6_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(k62_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(k62_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, opSYSCALL, opCLTS, opSYSRET, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opPREFETCH_a16, opFEMMS, op3DNOW_a16, @@ -1677,13 +1663,12 @@ const OpFn OP_TABLE(k62_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; #if defined(DEV_BRANCH) && defined(USE_CYRIX_6X86) -const OpFn OP_TABLE(c6x86mx_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(c6x86mx_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -1771,13 +1756,12 @@ const OpFn OP_TABLE(c6x86mx_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; #endif -const OpFn OP_TABLE(pentiumpro_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(pentiumpro_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -1865,12 +1849,11 @@ const OpFn OP_TABLE(pentiumpro_0f)[1024] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(pentium2_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(pentium2_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -1958,12 +1941,11 @@ const OpFn OP_TABLE(pentium2_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(pentium2d_0f)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(pentium2d_0f)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ op0F00_a16, op0F01_w_a16, opLAR_w_a16, opLSL_w_a16, ILLEGAL, ILLEGAL, opCLTS, ILLEGAL, opINVD, opWBINVD, ILLEGAL, ILLEGAL, ILLEGAL, opNOP, ILLEGAL, ILLEGAL, @@ -2051,12 +2033,11 @@ const OpFn OP_TABLE(pentium2d_0f)[1024] = /*d0*/ ILLEGAL, opPSRLW_a32, opPSRLD_a32, opPSRLQ_a32, ILLEGAL, opPMULLW_a32, ILLEGAL, ILLEGAL, opPSUBUSB_a32, opPSUBUSW_a32, NULL, opPAND_a32, opPADDUSB_a32, opPADDUSW_a32, NULL, opPANDN_a32, /*e0*/ ILLEGAL, opPSRAW_a32, opPSRAD_a32, ILLEGAL, ILLEGAL, opPMULHW_a32, ILLEGAL, ILLEGAL, opPSUBSB_a32, opPSUBSW_a32, NULL, opPOR_a32, opPADDSB_a32, opPADDSW_a32, NULL, opPXOR_a32, /*f0*/ ILLEGAL, opPSLLW_a32, opPSLLD_a32, opPSLLQ_a32, ILLEGAL, opPMADDWD_a32, ILLEGAL, ILLEGAL, opPSUBB_a32, opPSUBW_a32, opPSUBD_a32, ILLEGAL, opPADDB_a32, opPADDW_a32, opPADDD_a32, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(186)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(186)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2144,12 +2125,11 @@ const OpFn OP_TABLE(186)[1024] = /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, /*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(286)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(286)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2237,12 +2217,11 @@ const OpFn OP_TABLE(286)[1024] = /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, /*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(386)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(386)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ opADD_b_rmw_a16,opADD_w_rmw_a16,opADD_b_rm_a16, opADD_w_rm_a16, opADD_AL_imm, opADD_AX_imm, opPUSH_ES_w, opPOP_ES_w, opOR_b_rmw_a16, opOR_w_rmw_a16, opOR_b_rm_a16, opOR_w_rm_a16, opOR_AL_imm, opOR_AX_imm, opPUSH_CS_w, op0F_w_a16, @@ -2330,12 +2309,11 @@ const OpFn OP_TABLE(386)[1024] = /*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, /*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, /*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(REPE)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(REPE)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2423,12 +2401,11 @@ const OpFn OP_TABLE(REPE)[1024] = /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(REPNE)[1024] = -{ -// clang-format off +const OpFn OP_TABLE(REPNE)[1024] = { + // clang-format off /*16-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2516,5 +2493,5 @@ const OpFn OP_TABLE(REPNE)[1024] = /*d0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// clang-format on + // clang-format on }; diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 6d2b860de..6fc922b1e 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -32,52 +32,44 @@ #include "cpu.h" #include <86box/machine.h> -FPU fpus_none[] = -{ - {"None", "none", FPU_NONE}, - {NULL, NULL, 0} +FPU fpus_none[] = { + {"None", "none", FPU_NONE}, + { NULL, NULL, 0 } }; -FPU fpus_8088[] = -{ - {"None", "none", FPU_NONE}, - {"8087", "8087", FPU_8087}, - {NULL, NULL, 0} +FPU fpus_8088[] = { + {"None", "none", FPU_NONE}, + { "8087", "8087", FPU_8087}, + { NULL, NULL, 0 } }; -FPU fpus_80186[] = -{ - {"None", "none", FPU_NONE}, - {"8087", "8087", FPU_8087}, - {"80187", "80187", FPU_80187}, - {NULL, NULL, 0} +FPU fpus_80186[] = { + {"None", "none", FPU_NONE }, + { "8087", "8087", FPU_8087 }, + { "80187", "80187", FPU_80187}, + { NULL, NULL, 0 } }; -FPU fpus_80286[] = -{ - {"None", "none", FPU_NONE}, - {"287", "287", FPU_287}, - {"287XL","287xl", FPU_287XL}, - {NULL, NULL, 0} +FPU fpus_80286[] = { + {"None", "none", FPU_NONE }, + { "287", "287", FPU_287 }, + { "287XL", "287xl", FPU_287XL}, + { NULL, NULL, 0 } }; -FPU fpus_80386[] = -{ - {"None", "none", FPU_NONE}, - {"387", "387", FPU_387}, - {NULL, NULL, 0} +FPU fpus_80386[] = { + {"None", "none", FPU_NONE}, + { "387", "387", FPU_387 }, + { NULL, NULL, 0 } }; -FPU fpus_486sx[] = -{ - {"None", "none", FPU_NONE}, - {"487SX","487sx", FPU_487SX}, - {NULL, NULL, 0} +FPU fpus_486sx[] = { + {"None", "none", FPU_NONE }, + { "487SX", "487sx", FPU_487SX}, + { NULL, NULL, 0 } }; -FPU fpus_internal[] = -{ - {"Internal", "internal", FPU_INTERNAL}, - {NULL, NULL, 0} +FPU fpus_internal[] = { + {"Internal", "internal", FPU_INTERNAL}, + { NULL, NULL, 0 } }; - const cpu_family_t cpu_families[] = { -// clang-format off + // clang-format off { .package = CPU_PKG_8088, .manufacturer = "Intel", @@ -1147,959 +1139,958 @@ const cpu_family_t cpu_families[] = { }, { .package = 0, } -// clang-format on + // clang-format on }; /* Legacy CPU tables for backwards compatibility. */ static const cpu_legacy_table_t cpus_8088[] = { - {"8088", 4772728, 1}, - {"8088", 7159092, 1}, - {"8088", 8000000, 1}, - {"8088", 10000000, 1}, - {"8088", 12000000, 1}, - {"8088", 16000000, 1}, - {NULL, 0, 0} + {"8088", 4772728, 1}, + { "8088", 7159092, 1}, + { "8088", 8000000, 1}, + { "8088", 10000000, 1}, + { "8088", 12000000, 1}, + { "8088", 16000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_pcjr[] = { {"8088", 4772728, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_europc[] = { - {"8088_europc", 4772728, 1}, - {"8088_europc", 7159092, 1}, - {"8088_europc", 9545456, 1}, - {NULL, 0, 0} + {"8088_europc", 4772728, 1}, + { "8088_europc", 7159092, 1}, + { "8088_europc", 9545456, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_8086[] = { - {"8086", 7159092, 1}, - {"8086", 8000000, 1}, - {"8086", 9545456, 1}, - {"8086", 10000000, 1}, - {"8086", 12000000, 1}, - {"8086", 16000000, 1}, - {NULL, 0, 0} + {"8086", 7159092, 1}, + { "8086", 8000000, 1}, + { "8086", 9545456, 1}, + { "8086", 10000000, 1}, + { "8086", 12000000, 1}, + { "8086", 16000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_pc1512[] = { {"8086", 8000000, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_286[] = { - {"286", 6000000, 1}, - {"286", 8000000, 1}, - {"286", 10000000, 1}, - {"286", 12500000, 1}, - {"286", 16000000, 1}, - {"286", 20000000, 1}, - {"286", 25000000, 1}, - {NULL, 0, 0} + {"286", 6000000, 1}, + { "286", 8000000, 1}, + { "286", 10000000, 1}, + { "286", 12500000, 1}, + { "286", 16000000, 1}, + { "286", 20000000, 1}, + { "286", 25000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ibmat[] = { - {"286", 6000000, 1}, - {"286", 8000000, 1}, - {NULL, 0, 0} + {"286", 6000000, 1}, + { "286", 8000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ibmxt286[] = { {"286", 6000000, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ps1_m2011[] = { {"286", 10000000, 1}, - {NULL, 0, 0} + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ps2_m30_286[] = { - {"286", 10000000, 1}, - {"286", 12500000, 1}, - {"286", 16000000, 1}, - {"286", 20000000, 1}, - {"286", 25000000, 1}, - {NULL, 0, 0} + {"286", 10000000, 1}, + { "286", 12500000, 1}, + { "286", 16000000, 1}, + { "286", 20000000, 1}, + { "286", 25000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_i386SX[] = { - {"i386sx", 16000000, 1}, - {"i386sx", 20000000, 1}, - {"i386sx", 25000000, 1}, - {"i386sx", 33333333, 1}, - {"i386sx", 40000000, 1}, - {NULL, 0, 0} + {"i386sx", 16000000, 1}, + { "i386sx", 20000000, 1}, + { "i386sx", 25000000, 1}, + { "i386sx", 33333333, 1}, + { "i386sx", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_i386DX[] = { - {"i386dx", 16000000, 1}, - {"i386dx", 20000000, 1}, - {"i386dx", 25000000, 1}, - {"i386dx", 33333333, 1}, - {"i386dx", 40000000, 1}, - {"rapidcad", 25000000, 1}, - {"rapidcad", 33333333, 1}, - {"rapidcad", 40000000, 1}, - {NULL, 0, 0} + {"i386dx", 16000000, 1}, + { "i386dx", 20000000, 1}, + { "i386dx", 25000000, 1}, + { "i386dx", 33333333, 1}, + { "i386dx", 40000000, 1}, + { "rapidcad", 25000000, 1}, + { "rapidcad", 33333333, 1}, + { "rapidcad", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Am386SX[] = { - {"am386sx", 16000000, 1}, - {"am386sx", 20000000, 1}, - {"am386sx", 25000000, 1}, - {"am386sx", 33333333, 1}, - {"am386sx", 40000000, 1}, - {NULL, 0, 0} + {"am386sx", 16000000, 1}, + { "am386sx", 20000000, 1}, + { "am386sx", 25000000, 1}, + { "am386sx", 33333333, 1}, + { "am386sx", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Am386DX[] = { - {"am386dx", 25000000, 1}, - {"am386dx", 33333333, 1}, - {"am386dx", 40000000, 1}, - {NULL, 0, 0} + {"am386dx", 25000000, 1}, + { "am386dx", 33333333, 1}, + { "am386dx", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_ALiM6117[] = { - {"m6117", 33333333, 1}, - {"m6117", 40000000, 1}, - {NULL, 0, 0} + {"m6117", 33333333, 1}, + { "m6117", 40000000, 1}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_486SLC[] = { - {"cx486slc", 20000000, 1}, - {"cx486slc", 25000000, 1}, - {"cx486slc", 33333333, 1}, - {"cx486srx2", 32000000, 2}, - {"cx486srx2", 40000000, 2}, - {"cx486srx2", 50000000, 2}, - {NULL, 0, 0} + {"cx486slc", 20000000, 1}, + { "cx486slc", 25000000, 1}, + { "cx486slc", 33333333, 1}, + { "cx486srx2", 32000000, 2}, + { "cx486srx2", 40000000, 2}, + { "cx486srx2", 50000000, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_IBM486SLC[] = { - {"ibm486slc", 33333333, 1}, - {"ibm486slc2", 40000000, 2}, - {"ibm486slc2", 50000000, 2}, - {"ibm486slc2", 66666666, 2}, - {"ibm486slc3", 60000000, 3}, - {"ibm486slc3", 75000000, 3}, - {"ibm486slc3", 100000000, 3}, - {NULL, 0, 0} + {"ibm486slc", 33333333, 1}, + { "ibm486slc2", 40000000, 2}, + { "ibm486slc2", 50000000, 2}, + { "ibm486slc2", 66666666, 2}, + { "ibm486slc3", 60000000, 3}, + { "ibm486slc3", 75000000, 3}, + { "ibm486slc3", 100000000, 3}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_IBM486BL[] = { - {"ibm486bl2", 50000000, 2}, - {"ibm486bl2", 66666666, 2}, - {"ibm486bl3", 75000000, 3}, - {"ibm486bl3", 100000000, 3}, - {NULL, 0, 0} + {"ibm486bl2", 50000000, 2}, + { "ibm486bl2", 66666666, 2}, + { "ibm486bl3", 75000000, 3}, + { "ibm486bl3", 100000000, 3}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_486DLC[] = { - {"cx486dlc", 25000000, 1}, - {"cx486dlc", 33333333, 1}, - {"cx486dlc", 40000000, 1}, - {"cx486drx2", 32000000, 2}, - {"cx486drx2", 40000000, 2}, - {"cx486drx2", 50000000, 2}, - {"cx486drx2", 66666666, 2}, - {NULL, 0, 0} + {"cx486dlc", 25000000, 1}, + { "cx486dlc", 33333333, 1}, + { "cx486dlc", 40000000, 1}, + { "cx486drx2", 32000000, 2}, + { "cx486drx2", 40000000, 2}, + { "cx486drx2", 50000000, 2}, + { "cx486drx2", 66666666, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_i486S1[] = { - {"i486sx", 16000000, 1}, - {"i486sx", 20000000, 1}, - {"i486sx", 25000000, 1}, - {"i486sx", 33333333, 1}, - {"i486sx2", 50000000, 2}, - {"i486sx2", 66666666, 2}, - {"i486dx", 25000000, 1}, - {"i486dx", 33333333, 1}, - {"i486dx", 50000000, 1}, - {"i486dx2", 40000000, 2}, - {"i486dx2", 50000000, 2}, - {"i486dx2", 66666666, 2}, - {"idx4_od", 75000000, 3}, - {"idx4_od", 100000000, 3}, - {NULL, 0, 0} + {"i486sx", 16000000, 1}, + { "i486sx", 20000000, 1}, + { "i486sx", 25000000, 1}, + { "i486sx", 33333333, 1}, + { "i486sx2", 50000000, 2}, + { "i486sx2", 66666666, 2}, + { "i486dx", 25000000, 1}, + { "i486dx", 33333333, 1}, + { "i486dx", 50000000, 1}, + { "i486dx2", 40000000, 2}, + { "i486dx2", 50000000, 2}, + { "i486dx2", 66666666, 2}, + { "idx4_od", 75000000, 3}, + { "idx4_od", 100000000, 3}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Am486S1[] = { - {"am486sx", 33333333, 1}, - {"am486sx", 40000000, 1}, - {"am486sx2", 50000000, 2}, - {"am486sx2", 66666666, 2}, - {"am486dx", 33333333, 1}, - {"am486dx", 40000000, 1}, - {"am486dx2", 50000000, 2}, - {"am486dx2", 66666666, 2}, - {"am486dx2", 80000000, 2}, - {NULL, 0, 0} + {"am486sx", 33333333, 1}, + { "am486sx", 40000000, 1}, + { "am486sx2", 50000000, 2}, + { "am486sx2", 66666666, 2}, + { "am486dx", 33333333, 1}, + { "am486dx", 40000000, 1}, + { "am486dx2", 50000000, 2}, + { "am486dx2", 66666666, 2}, + { "am486dx2", 80000000, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_Cx486S1[] = { - {"cx486s", 25000000, 1.0}, - {"cx486s", 33333333, 1.0}, - {"cx486s", 40000000, 1.0}, - {"cx486dx", 33333333, 1.0}, - {"cx486dx", 40000000, 1.0}, - {"cx486dx2", 50000000, 2.0}, - {"cx486dx2", 66666666, 2.0}, - {"cx486dx2", 80000000, 2.0}, - {NULL, 0, 0} + {"cx486s", 25000000, 1.0}, + { "cx486s", 33333333, 1.0}, + { "cx486s", 40000000, 1.0}, + { "cx486dx", 33333333, 1.0}, + { "cx486dx", 40000000, 1.0}, + { "cx486dx2", 50000000, 2.0}, + { "cx486dx2", 66666666, 2.0}, + { "cx486dx2", 80000000, 2.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_i486[] = { - {"i486sx", 16000000, 1.0}, - {"i486sx", 20000000, 1.0}, - {"i486sx", 25000000, 1.0}, - {"i486sx", 33333333, 1.0}, - {"i486sx2", 50000000, 2.0}, - {"i486sx2", 66666666, 2.0}, - {"i486dx", 25000000, 1.0}, - {"i486dx", 33333333, 1.0}, - {"i486dx", 50000000, 1.0}, - {"i486dx2", 40000000, 2.0}, - {"i486dx2", 50000000, 2.0}, - {"i486dx2", 66666666, 2.0}, - {"idx4", 75000000, 3.0}, - {"idx4", 100000000, 3.0}, - {"idx4_od", 75000000, 3.0}, - {"idx4_od", 100000000, 3.0}, - {"pentium_p24t", 62500000, 2.5}, - {"pentium_p24t", 83333333, 2.5}, - {NULL, 0, 0} + {"i486sx", 16000000, 1.0}, + { "i486sx", 20000000, 1.0}, + { "i486sx", 25000000, 1.0}, + { "i486sx", 33333333, 1.0}, + { "i486sx2", 50000000, 2.0}, + { "i486sx2", 66666666, 2.0}, + { "i486dx", 25000000, 1.0}, + { "i486dx", 33333333, 1.0}, + { "i486dx", 50000000, 1.0}, + { "i486dx2", 40000000, 2.0}, + { "i486dx2", 50000000, 2.0}, + { "i486dx2", 66666666, 2.0}, + { "idx4", 75000000, 3.0}, + { "idx4", 100000000, 3.0}, + { "idx4_od", 75000000, 3.0}, + { "idx4_od", 100000000, 3.0}, + { "pentium_p24t", 62500000, 2.5}, + { "pentium_p24t", 83333333, 2.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_i486_PC330[] = { - {"i486dx2", 50000000, 2.0}, - {"i486dx2", 66666666, 2.0}, - {"idx4", 75000000, 3.0}, - {"idx4", 100000000, 3.0}, - {"pentium_p24t", 62500000, 2.5}, - {"pentium_p24t", 83333333, 2.5}, - {NULL, 0, 0} + {"i486dx2", 50000000, 2.0}, + { "i486dx2", 66666666, 2.0}, + { "idx4", 75000000, 3.0}, + { "idx4", 100000000, 3.0}, + { "pentium_p24t", 62500000, 2.5}, + { "pentium_p24t", 83333333, 2.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Am486[] = { - {"am486sx", 33333333, 1.0}, - {"am486sx", 40000000, 1.0}, - {"am486sx2", 50000000, 2.0}, - {"am486sx2", 66666666, 2.0}, - {"am486dx", 33333333, 1.0}, - {"am486dx", 40000000, 1.0}, - {"am486dx2", 50000000, 2.0}, - {"am486dx2", 66666666, 2.0}, - {"am486dx2", 80000000, 2.0}, - {"am486dx4", 75000000, 3.0}, - {"am486dx4", 90000000, 3.0}, - {"am486dx4", 100000000, 3.0}, - {"am486dx4", 120000000, 3.0}, - {"am5x86", 133333333, 4.0}, - {"am5x86", 150000000, 3.0}, - {"am5x86", 160000000, 4.0}, - {NULL, 0, 0} + {"am486sx", 33333333, 1.0}, + { "am486sx", 40000000, 1.0}, + { "am486sx2", 50000000, 2.0}, + { "am486sx2", 66666666, 2.0}, + { "am486dx", 33333333, 1.0}, + { "am486dx", 40000000, 1.0}, + { "am486dx2", 50000000, 2.0}, + { "am486dx2", 66666666, 2.0}, + { "am486dx2", 80000000, 2.0}, + { "am486dx4", 75000000, 3.0}, + { "am486dx4", 90000000, 3.0}, + { "am486dx4", 100000000, 3.0}, + { "am486dx4", 120000000, 3.0}, + { "am5x86", 133333333, 4.0}, + { "am5x86", 150000000, 3.0}, + { "am5x86", 160000000, 4.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Cx486[] = { - {"cx486s", 25000000, 1.0}, - {"cx486s", 33333333, 1.0}, - {"cx486s", 40000000, 1.0}, - {"cx486dx", 33333333, 1.0}, - {"cx486dx", 40000000, 1.0}, - {"cx486dx2", 50000000, 2.0}, - {"cx486dx2", 66666666, 2.0}, - {"cx486dx2", 80000000, 2.0}, - {"cx486dx4", 75000000, 3.0}, - {"cx486dx4", 100000000, 3.0}, - {"cx5x86", 80000000, 2.0}, - {"cx5x86", 100000000, 3.0}, - {"cx5x86", 120000000, 3.0}, - {"cx5x86", 133333333, 4.0}, - {NULL, 0, 0} + {"cx486s", 25000000, 1.0}, + { "cx486s", 33333333, 1.0}, + { "cx486s", 40000000, 1.0}, + { "cx486dx", 33333333, 1.0}, + { "cx486dx", 40000000, 1.0}, + { "cx486dx2", 50000000, 2.0}, + { "cx486dx2", 66666666, 2.0}, + { "cx486dx2", 80000000, 2.0}, + { "cx486dx4", 75000000, 3.0}, + { "cx486dx4", 100000000, 3.0}, + { "cx5x86", 80000000, 2.0}, + { "cx5x86", 100000000, 3.0}, + { "cx5x86", 120000000, 3.0}, + { "cx5x86", 133333333, 4.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_STPCDX[] = { - {"stpc_dx", 66666666, 1.0}, - {"stpc_dx", 75000000, 1.0}, - {NULL, 0, 0} + {"stpc_dx", 66666666, 1.0}, + { "stpc_dx", 75000000, 1.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_STPCDX2[] = { {"stpc_dx2", 133333333, 2.0}, - {NULL, 0, 0} + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_6x863V[] = { - {"cx6x86", 80000000, 2.0}, - {"cx6x86", 100000000, 2.0}, - {"cx6x86", 110000000, 2.0}, - {"cx6x86", 120000000, 2.0}, - {"cx6x86", 133333333, 2.0}, - {"cx6x86", 150000000, 2.0}, - {NULL, 0, 0} + {"cx6x86", 80000000, 2.0}, + { "cx6x86", 100000000, 2.0}, + { "cx6x86", 110000000, 2.0}, + { "cx6x86", 120000000, 2.0}, + { "cx6x86", 133333333, 2.0}, + { "cx6x86", 150000000, 2.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_6x86[] = { - {"cx6x86", 80000000, 2.0}, - {"cx6x86", 100000000, 2.0}, - {"cx6x86", 110000000, 2.0}, - {"cx6x86", 120000000, 2.0}, - {"cx6x86", 133333333, 2.0}, - {"cx6x86", 150000000, 2.0}, - {"cx6x86l", 110000000, 2.0}, - {"cx6x86l", 120000000, 2.0}, - {"cx6x86l", 133333333, 2.0}, - {"cx6x86l", 150000000, 2.0}, - {"cx6x86mx", 133333333, 2.0}, - {"cx6x86mx", 166666666, 2.5}, - {"cx6x86mx", 187500000, 2.5}, - {"cx6x86mx", 208333333, 2.5}, - {"mii", 233333333, 3.5}, - {"mii", 250000000, 3.0}, - {NULL, 0, 0} + {"cx6x86", 80000000, 2.0}, + { "cx6x86", 100000000, 2.0}, + { "cx6x86", 110000000, 2.0}, + { "cx6x86", 120000000, 2.0}, + { "cx6x86", 133333333, 2.0}, + { "cx6x86", 150000000, 2.0}, + { "cx6x86l", 110000000, 2.0}, + { "cx6x86l", 120000000, 2.0}, + { "cx6x86l", 133333333, 2.0}, + { "cx6x86l", 150000000, 2.0}, + { "cx6x86mx", 133333333, 2.0}, + { "cx6x86mx", 166666666, 2.5}, + { "cx6x86mx", 187500000, 2.5}, + { "cx6x86mx", 208333333, 2.5}, + { "mii", 233333333, 3.5}, + { "mii", 250000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_6x86SS7[] = { - {"cx6x86", 80000000, 2.0}, - {"cx6x86", 100000000, 2.0}, - {"cx6x86", 110000000, 2.0}, - {"cx6x86", 120000000, 2.0}, - {"cx6x86", 133333333, 2.0}, - {"cx6x86", 150000000, 2.0}, - {"cx6x86l", 110000000, 2.0}, - {"cx6x86l", 120000000, 2.0}, - {"cx6x86l", 133333333, 2.0}, - {"cx6x86l", 150000000, 2.0}, - {"cx6x86mx", 133333333, 2.0}, - {"cx6x86mx", 166666666, 2.5}, - {"cx6x86mx", 187500000, 2.5}, - {"cx6x86mx", 208333333, 2.5}, - {"mii", 233333333, 3.5}, - {"mii", 250000000, 3.0}, - {"mii", 250000000, 2.5}, - {"mii", 285000000, 3.0}, - {"mii", 300000000, 3.0}, - {NULL, 0, 0} + {"cx6x86", 80000000, 2.0}, + { "cx6x86", 100000000, 2.0}, + { "cx6x86", 110000000, 2.0}, + { "cx6x86", 120000000, 2.0}, + { "cx6x86", 133333333, 2.0}, + { "cx6x86", 150000000, 2.0}, + { "cx6x86l", 110000000, 2.0}, + { "cx6x86l", 120000000, 2.0}, + { "cx6x86l", 133333333, 2.0}, + { "cx6x86l", 150000000, 2.0}, + { "cx6x86mx", 133333333, 2.0}, + { "cx6x86mx", 166666666, 2.5}, + { "cx6x86mx", 187500000, 2.5}, + { "cx6x86mx", 208333333, 2.5}, + { "mii", 233333333, 3.5}, + { "mii", 250000000, 3.0}, + { "mii", 250000000, 2.5}, + { "mii", 285000000, 3.0}, + { "mii", 300000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_WinChip[] = { - {"winchip", 75000000, 1.5}, - {"winchip", 90000000, 1.5}, - {"winchip", 100000000, 1.5}, - {"winchip", 120000000, 2.0}, - {"winchip", 133333333, 2.0}, - {"winchip", 150000000, 2.5}, - {"winchip", 166666666, 2.5}, - {"winchip", 180000000, 3.0}, - {"winchip", 200000000, 3.0}, - {"winchip", 225000000, 3.0}, - {"winchip", 240000000, 4.0}, - {"winchip2", 200000000, 3.0}, - {"winchip2", 225000000, 3.0}, - {"winchip2", 240000000, 4.0}, - {"winchip2", 250000000, 3.0}, - {"winchip2a", 200000000, 3.0}, - {"winchip2a", 233333333, 3.5}, - {NULL, 0, 0} + {"winchip", 75000000, 1.5}, + { "winchip", 90000000, 1.5}, + { "winchip", 100000000, 1.5}, + { "winchip", 120000000, 2.0}, + { "winchip", 133333333, 2.0}, + { "winchip", 150000000, 2.5}, + { "winchip", 166666666, 2.5}, + { "winchip", 180000000, 3.0}, + { "winchip", 200000000, 3.0}, + { "winchip", 225000000, 3.0}, + { "winchip", 240000000, 4.0}, + { "winchip2", 200000000, 3.0}, + { "winchip2", 225000000, 3.0}, + { "winchip2", 240000000, 4.0}, + { "winchip2", 250000000, 3.0}, + { "winchip2a", 200000000, 3.0}, + { "winchip2a", 233333333, 3.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_WinChip_SS7[] = { - {"winchip", 75000000, 1.5}, - {"winchip", 90000000, 1.5}, - {"winchip", 100000000, 1.5}, - {"winchip", 120000000, 2.0}, - {"winchip", 133333333, 2.0}, - {"winchip", 150000000, 2.5}, - {"winchip", 166666666, 2.5}, - {"winchip", 180000000, 3.0}, - {"winchip", 200000000, 3.0}, - {"winchip", 225000000, 3.0}, - {"winchip", 240000000, 4.0}, - {"winchip2", 200000000, 3.0}, - {"winchip2", 225000000, 3.0}, - {"winchip2", 240000000, 4.0}, - {"winchip2", 250000000, 3.0}, - {"winchip2a", 200000000, 3.0}, - {"winchip2a", 233333333, 3.5}, - {"winchip2a", 233333333, 7.0}, - {"winchip2a", 250000000, 2.5}, - {NULL, 0, 0} + {"winchip", 75000000, 1.5}, + { "winchip", 90000000, 1.5}, + { "winchip", 100000000, 1.5}, + { "winchip", 120000000, 2.0}, + { "winchip", 133333333, 2.0}, + { "winchip", 150000000, 2.5}, + { "winchip", 166666666, 2.5}, + { "winchip", 180000000, 3.0}, + { "winchip", 200000000, 3.0}, + { "winchip", 225000000, 3.0}, + { "winchip", 240000000, 4.0}, + { "winchip2", 200000000, 3.0}, + { "winchip2", 225000000, 3.0}, + { "winchip2", 240000000, 4.0}, + { "winchip2", 250000000, 3.0}, + { "winchip2a", 200000000, 3.0}, + { "winchip2a", 233333333, 3.5}, + { "winchip2a", 233333333, 7.0}, + { "winchip2a", 250000000, 2.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Pentium5V[] = { - {"pentium_p5", 60000000, 1}, - {"pentium_p5", 66666666, 1}, - {"pentium_p54c_od5v", 120000000, 2}, - {"pentium_p54c_od5v", 133333333, 2}, - {NULL, 0, 0} + {"pentium_p5", 60000000, 1}, + { "pentium_p5", 66666666, 1}, + { "pentium_p54c_od5v", 120000000, 2}, + { "pentium_p54c_od5v", 133333333, 2}, + { NULL, 0, 0} }; static const cpu_legacy_table_t cpus_PentiumS5[] = { - {"pentium_p54c", 75000000, 1.5}, - {"pentium_p55c_od", 75000000, 1.5}, - {"pentium_p54c", 90000000, 1.5}, - {"pentium_p54c", 100000000, 2.0}, - {"pentium_p54c", 100000000, 1.5}, - {"pentium_p54c", 120000000, 2.0}, - {"pentium_p54c", 133333333, 2.0}, - {"pentium_p54c_od3v", 125000000, 3.0}, - {"pentium_p54c_od3v", 150000000, 2.5}, - {"pentium_p54c_od3v", 166666666, 2.5}, - {"pentium_p55c_od", 125000000, 2.5}, - {"pentium_p55c_od", 150000000, 2.5}, - {"pentium_p55c_od", 166000000, 2.5}, - {"pentium_p55c_od", 180000000, 3.0}, - {"pentium_p55c_od", 200000000, 3.0}, - {NULL, 0, 0} + {"pentium_p54c", 75000000, 1.5}, + { "pentium_p55c_od", 75000000, 1.5}, + { "pentium_p54c", 90000000, 1.5}, + { "pentium_p54c", 100000000, 2.0}, + { "pentium_p54c", 100000000, 1.5}, + { "pentium_p54c", 120000000, 2.0}, + { "pentium_p54c", 133333333, 2.0}, + { "pentium_p54c_od3v", 125000000, 3.0}, + { "pentium_p54c_od3v", 150000000, 2.5}, + { "pentium_p54c_od3v", 166666666, 2.5}, + { "pentium_p55c_od", 125000000, 2.5}, + { "pentium_p55c_od", 150000000, 2.5}, + { "pentium_p55c_od", 166000000, 2.5}, + { "pentium_p55c_od", 180000000, 3.0}, + { "pentium_p55c_od", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Pentium3V[] = { - {"pentium_p54c", 75000000, 1.5}, - {"pentium_p55c_od", 75000000, 1.5}, - {"pentium_p54c", 90000000, 1.5}, - {"pentium_p54c", 100000000, 2.0}, - {"pentium_p54c", 100000000, 1.5}, - {"pentium_p54c", 120000000, 2.0}, - {"pentium_p54c", 133333333, 2.0}, - {"pentium_p54c", 150000000, 2.5}, - {"pentium_p54c", 166666666, 2.5}, - {"pentium_p54c", 200000000, 3.0}, - {"pentium_p54c_od3v", 125000000, 2.5}, - {"pentium_p54c_od3v", 150000000, 2.5}, - {"pentium_p54c_od3v", 166666666, 2.5}, - {"pentium_p55c_od", 125000000, 2.5}, - {"pentium_p55c_od", 150000000, 2.5}, - {"pentium_p55c_od", 166000000, 2.5}, - {"pentium_p55c_od", 180000000, 3.0}, - {"pentium_p55c_od", 200000000, 3.0}, - {NULL, 0, 0} + {"pentium_p54c", 75000000, 1.5}, + { "pentium_p55c_od", 75000000, 1.5}, + { "pentium_p54c", 90000000, 1.5}, + { "pentium_p54c", 100000000, 2.0}, + { "pentium_p54c", 100000000, 1.5}, + { "pentium_p54c", 120000000, 2.0}, + { "pentium_p54c", 133333333, 2.0}, + { "pentium_p54c", 150000000, 2.5}, + { "pentium_p54c", 166666666, 2.5}, + { "pentium_p54c", 200000000, 3.0}, + { "pentium_p54c_od3v", 125000000, 2.5}, + { "pentium_p54c_od3v", 150000000, 2.5}, + { "pentium_p54c_od3v", 166666666, 2.5}, + { "pentium_p55c_od", 125000000, 2.5}, + { "pentium_p55c_od", 150000000, 2.5}, + { "pentium_p55c_od", 166000000, 2.5}, + { "pentium_p55c_od", 180000000, 3.0}, + { "pentium_p55c_od", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Pentium[] = { - {"pentium_p54c", 75000000, 1.5}, - {"pentium_p55c_od", 75000000, 1.5}, - {"pentium_p54c", 90000000, 1.5}, - {"pentium_p54c", 100000000, 2.0}, - {"pentium_p54c", 100000000, 1.5}, - {"pentium_p54c", 120000000, 2.0}, - {"pentium_p54c", 133333333, 2.0}, - {"pentium_p54c", 150000000, 2.5}, - {"pentium_p54c", 166666666, 2.5}, - {"pentium_p54c", 200000000, 3.0}, - {"pentium_p55c", 166666666, 2.5}, - {"pentium_p55c", 200000000, 3.0}, - {"pentium_p55c", 233333333, 3.5}, - {"pentium_tillamook", 120000000, 2.0}, - {"pentium_tillamook", 133333333, 2.0}, - {"pentium_tillamook", 150000000, 2.5}, - {"pentium_tillamook", 166666666, 2.5}, - {"pentium_tillamook", 200000000, 3.0}, - {"pentium_tillamook", 233333333, 3.5}, - {"pentium_tillamook", 266666666, 4.0}, - {"pentium_tillamook", 300000000, 4.5}, - {"pentium_p54c_od3v", 125000000, 2.5}, - {"pentium_p54c_od3v", 150000000, 2.5}, - {"pentium_p54c_od3v", 166666666, 2.5}, - {"pentium_p55c_od", 125000000, 2.5}, - {"pentium_p55c_od", 150000000, 2.5}, - {"pentium_p55c_od", 166000000, 2.5}, - {"pentium_p55c_od", 180000000, 3.0}, - {"pentium_p55c_od", 200000000, 3.0}, - {NULL, 0, 0} + {"pentium_p54c", 75000000, 1.5}, + { "pentium_p55c_od", 75000000, 1.5}, + { "pentium_p54c", 90000000, 1.5}, + { "pentium_p54c", 100000000, 2.0}, + { "pentium_p54c", 100000000, 1.5}, + { "pentium_p54c", 120000000, 2.0}, + { "pentium_p54c", 133333333, 2.0}, + { "pentium_p54c", 150000000, 2.5}, + { "pentium_p54c", 166666666, 2.5}, + { "pentium_p54c", 200000000, 3.0}, + { "pentium_p55c", 166666666, 2.5}, + { "pentium_p55c", 200000000, 3.0}, + { "pentium_p55c", 233333333, 3.5}, + { "pentium_tillamook", 120000000, 2.0}, + { "pentium_tillamook", 133333333, 2.0}, + { "pentium_tillamook", 150000000, 2.5}, + { "pentium_tillamook", 166666666, 2.5}, + { "pentium_tillamook", 200000000, 3.0}, + { "pentium_tillamook", 233333333, 3.5}, + { "pentium_tillamook", 266666666, 4.0}, + { "pentium_tillamook", 300000000, 4.5}, + { "pentium_p54c_od3v", 125000000, 2.5}, + { "pentium_p54c_od3v", 150000000, 2.5}, + { "pentium_p54c_od3v", 166666666, 2.5}, + { "pentium_p55c_od", 125000000, 2.5}, + { "pentium_p55c_od", 150000000, 2.5}, + { "pentium_p55c_od", 166000000, 2.5}, + { "pentium_p55c_od", 180000000, 3.0}, + { "pentium_p55c_od", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_K5[] = { - {"k5_5k86", 75000000, 1.5}, - {"k5_ssa5", 75000000, 1.5}, - {"k5_5k86", 90000000, 1.5}, - {"k5_ssa5", 90000000, 1.5}, - {"k5_5k86", 100000000, 1.5}, - {"k5_ssa5", 100000000, 1.5}, - {"k5_5k86", 120000000, 2.0}, - {"k5_5k86", 133333333, 2.0}, - {"k5_5k86", 150000000, 2.5}, - {"k5_5k86", 166666666, 2.5}, - {"k5_5k86", 200000000, 3.0}, - {NULL, 0, 0} + {"k5_5k86", 75000000, 1.5}, + { "k5_ssa5", 75000000, 1.5}, + { "k5_5k86", 90000000, 1.5}, + { "k5_ssa5", 90000000, 1.5}, + { "k5_5k86", 100000000, 1.5}, + { "k5_ssa5", 100000000, 1.5}, + { "k5_5k86", 120000000, 2.0}, + { "k5_5k86", 133333333, 2.0}, + { "k5_5k86", 150000000, 2.5}, + { "k5_5k86", 166666666, 2.5}, + { "k5_5k86", 200000000, 3.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_K56[] = { - {"k6_m6", 66666666, 1.0}, - {"k6_m6", 100000000, 1.5}, - {"k6_m6", 133333333, 2.0}, - {"k6_m6", 166666666, 2.5}, - {"k6_m6", 200000000, 3.0}, - {"k6_m6", 233333333, 3.5}, - {"k6_m7", 100000000, 1.5}, - {"k6_m7", 133333333, 2.0}, - {"k6_m7", 166666666, 2.5}, - {"k6_m7", 200000000, 3.0}, - {"k6_m7", 233333333, 3.5}, - {"k6_m7", 266666666, 4.0}, - {"k6_m7", 300000000, 4.5}, - {"k6_2", 100000000, 1.5}, - {"k6_2", 133333333, 2.0}, - {"k6_2", 166666666, 2.5}, - {"k6_2", 200000000, 3.0}, - {"k6_2", 233333333, 3.5}, - {"k6_2", 266666666, 4.0}, - {"k6_2", 300000000, 4.5}, - {"k6_2", 366666666, 5.5}, - {NULL, 0, 0} + {"k6_m6", 66666666, 1.0}, + { "k6_m6", 100000000, 1.5}, + { "k6_m6", 133333333, 2.0}, + { "k6_m6", 166666666, 2.5}, + { "k6_m6", 200000000, 3.0}, + { "k6_m6", 233333333, 3.5}, + { "k6_m7", 100000000, 1.5}, + { "k6_m7", 133333333, 2.0}, + { "k6_m7", 166666666, 2.5}, + { "k6_m7", 200000000, 3.0}, + { "k6_m7", 233333333, 3.5}, + { "k6_m7", 266666666, 4.0}, + { "k6_m7", 300000000, 4.5}, + { "k6_2", 100000000, 1.5}, + { "k6_2", 133333333, 2.0}, + { "k6_2", 166666666, 2.5}, + { "k6_2", 200000000, 3.0}, + { "k6_2", 233333333, 3.5}, + { "k6_2", 266666666, 4.0}, + { "k6_2", 300000000, 4.5}, + { "k6_2", 366666666, 5.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_K56_SS7[] = { - {"k6_m6", 66666666, 1.0}, - {"k6_m6", 100000000, 1.5}, - {"k6_m6", 133333333, 2.0}, - {"k6_m6", 166666666, 2.5}, - {"k6_m6", 200000000, 3.0}, - {"k6_m6", 233333333, 3.5}, - {"k6_m7", 100000000, 1.5}, - {"k6_m7", 133333333, 2.0}, - {"k6_m7", 166666666, 2.5}, - {"k6_m7", 200000000, 3.0}, - {"k6_m7", 233333333, 3.5}, - {"k6_m7", 266666666, 4.0}, - {"k6_m7", 300000000, 4.5}, - {"k6_2", 100000000, 1.5}, - {"k6_2", 133333333, 2.0}, - {"k6_2", 166666666, 2.5}, - {"k6_2", 200000000, 3.0}, - {"k6_2", 233333333, 3.5}, - {"k6_2", 266666666, 4.0}, - {"k6_2", 300000000, 3.0}, - {"k6_2", 332500000, 3.5}, - {"k6_2", 350000000, 3.5}, - {"k6_2", 366666666, 5.5}, - {"k6_2", 380000000, 4.0}, - {"k6_2", 400000000, 4.0}, - {"k6_2", 450000000, 4.5}, - {"k6_2", 475000000, 5.0}, - {"k6_2", 500000000, 5.0}, - {"k6_2", 533333333, 5.5}, - {"k6_2", 550000000, 5.5}, - {"k6_2p", 100000000, 1.5}, - {"k6_2p", 133333333, 2.0}, - {"k6_2p", 166666666, 2.5}, - {"k6_2p", 200000000, 3.0}, - {"k6_2p", 233333333, 3.5}, - {"k6_2p", 266666666, 4.0}, - {"k6_2p", 300000000, 3.0}, - {"k6_2p", 332500000, 3.5}, - {"k6_2p", 350000000, 3.5}, - {"k6_2p", 366666666, 5.5}, - {"k6_2p", 380000000, 4.0}, - {"k6_2p", 400000000, 4.0}, - {"k6_2p", 450000000, 4.5}, - {"k6_2p", 475000000, 5.0}, - {"k6_2p", 500000000, 5.0}, - {"k6_2p", 533333333, 5.5}, - {"k6_2p", 550000000, 5.5}, - {"k6_3", 100000000, 1.5}, - {"k6_3", 133333333, 2.0}, - {"k6_3", 166666666, 2.5}, - {"k6_3", 200000000, 3.0}, - {"k6_3", 233333333, 3.5}, - {"k6_3", 266666666, 4.0}, - {"k6_3", 300000000, 3.0}, - {"k6_3", 332500000, 3.5}, - {"k6_3", 350000000, 3.5}, - {"k6_3", 366666666, 5.5}, - {"k6_3", 380000000, 4.0}, - {"k6_3", 400000000, 4.0}, - {"k6_3", 450000000, 4.5}, - {"k6_3p", 75000000, 1.5}, - {"k6_3p", 100000000, 1.5}, - {"k6_3p", 133333333, 2.0}, - {"k6_3p", 166666666, 2.5}, - {"k6_3p", 200000000, 3.0}, - {"k6_3p", 233333333, 3.5}, - {"k6_3p", 266666666, 4.0}, - {"k6_3p", 300000000, 3.0}, - {"k6_3p", 332500000, 3.5}, - {"k6_3p", 350000000, 3.5}, - {"k6_3p", 366666666, 5.5}, - {"k6_3p", 380000000, 4.0}, - {"k6_3p", 400000000, 4.0}, - {"k6_3p", 450000000, 4.5}, - {"k6_3p", 475000000, 5.0}, - {"k6_3p", 500000000, 5.0}, - {NULL, 0, 0} + {"k6_m6", 66666666, 1.0}, + { "k6_m6", 100000000, 1.5}, + { "k6_m6", 133333333, 2.0}, + { "k6_m6", 166666666, 2.5}, + { "k6_m6", 200000000, 3.0}, + { "k6_m6", 233333333, 3.5}, + { "k6_m7", 100000000, 1.5}, + { "k6_m7", 133333333, 2.0}, + { "k6_m7", 166666666, 2.5}, + { "k6_m7", 200000000, 3.0}, + { "k6_m7", 233333333, 3.5}, + { "k6_m7", 266666666, 4.0}, + { "k6_m7", 300000000, 4.5}, + { "k6_2", 100000000, 1.5}, + { "k6_2", 133333333, 2.0}, + { "k6_2", 166666666, 2.5}, + { "k6_2", 200000000, 3.0}, + { "k6_2", 233333333, 3.5}, + { "k6_2", 266666666, 4.0}, + { "k6_2", 300000000, 3.0}, + { "k6_2", 332500000, 3.5}, + { "k6_2", 350000000, 3.5}, + { "k6_2", 366666666, 5.5}, + { "k6_2", 380000000, 4.0}, + { "k6_2", 400000000, 4.0}, + { "k6_2", 450000000, 4.5}, + { "k6_2", 475000000, 5.0}, + { "k6_2", 500000000, 5.0}, + { "k6_2", 533333333, 5.5}, + { "k6_2", 550000000, 5.5}, + { "k6_2p", 100000000, 1.5}, + { "k6_2p", 133333333, 2.0}, + { "k6_2p", 166666666, 2.5}, + { "k6_2p", 200000000, 3.0}, + { "k6_2p", 233333333, 3.5}, + { "k6_2p", 266666666, 4.0}, + { "k6_2p", 300000000, 3.0}, + { "k6_2p", 332500000, 3.5}, + { "k6_2p", 350000000, 3.5}, + { "k6_2p", 366666666, 5.5}, + { "k6_2p", 380000000, 4.0}, + { "k6_2p", 400000000, 4.0}, + { "k6_2p", 450000000, 4.5}, + { "k6_2p", 475000000, 5.0}, + { "k6_2p", 500000000, 5.0}, + { "k6_2p", 533333333, 5.5}, + { "k6_2p", 550000000, 5.5}, + { "k6_3", 100000000, 1.5}, + { "k6_3", 133333333, 2.0}, + { "k6_3", 166666666, 2.5}, + { "k6_3", 200000000, 3.0}, + { "k6_3", 233333333, 3.5}, + { "k6_3", 266666666, 4.0}, + { "k6_3", 300000000, 3.0}, + { "k6_3", 332500000, 3.5}, + { "k6_3", 350000000, 3.5}, + { "k6_3", 366666666, 5.5}, + { "k6_3", 380000000, 4.0}, + { "k6_3", 400000000, 4.0}, + { "k6_3", 450000000, 4.5}, + { "k6_3p", 75000000, 1.5}, + { "k6_3p", 100000000, 1.5}, + { "k6_3p", 133333333, 2.0}, + { "k6_3p", 166666666, 2.5}, + { "k6_3p", 200000000, 3.0}, + { "k6_3p", 233333333, 3.5}, + { "k6_3p", 266666666, 4.0}, + { "k6_3p", 300000000, 3.0}, + { "k6_3p", 332500000, 3.5}, + { "k6_3p", 350000000, 3.5}, + { "k6_3p", 366666666, 5.5}, + { "k6_3p", 380000000, 4.0}, + { "k6_3p", 400000000, 4.0}, + { "k6_3p", 450000000, 4.5}, + { "k6_3p", 475000000, 5.0}, + { "k6_3p", 500000000, 5.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumPro[] = { - {"pentiumpro", 50000000, 1.0}, - {"pentiumpro", 60000000, 1.0}, - {"pentiumpro", 66666666, 1.0}, - {"pentiumpro", 75000000, 1.5}, - {"pentiumpro", 150000000, 2.5}, - {"pentiumpro", 166666666, 2.5}, - {"pentiumpro", 180000000, 3.0}, - {"pentiumpro", 200000000, 3.0}, - {"pentium2_od", 50000000, 1.0}, - {"pentium2_od", 60000000, 1.0}, - {"pentium2_od", 66666666, 1.0}, - {"pentium2_od", 75000000, 1.5}, - {"pentium2_od", 210000000, 3.5}, - {"pentium2_od", 233333333, 3.5}, - {"pentium2_od", 240000000, 4.0}, - {"pentium2_od", 266666666, 4.0}, - {"pentium2_od", 270000000, 4.5}, - {"pentium2_od", 300000000, 4.5}, - {"pentium2_od", 300000000, 5.0}, - {"pentium2_od", 333333333, 5.0}, - {NULL, 0, 0} + {"pentiumpro", 50000000, 1.0}, + { "pentiumpro", 60000000, 1.0}, + { "pentiumpro", 66666666, 1.0}, + { "pentiumpro", 75000000, 1.5}, + { "pentiumpro", 150000000, 2.5}, + { "pentiumpro", 166666666, 2.5}, + { "pentiumpro", 180000000, 3.0}, + { "pentiumpro", 200000000, 3.0}, + { "pentium2_od", 50000000, 1.0}, + { "pentium2_od", 60000000, 1.0}, + { "pentium2_od", 66666666, 1.0}, + { "pentium2_od", 75000000, 1.5}, + { "pentium2_od", 210000000, 3.5}, + { "pentium2_od", 233333333, 3.5}, + { "pentium2_od", 240000000, 4.0}, + { "pentium2_od", 266666666, 4.0}, + { "pentium2_od", 270000000, 4.5}, + { "pentium2_od", 300000000, 4.5}, + { "pentium2_od", 300000000, 5.0}, + { "pentium2_od", 333333333, 5.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumII66[] = { - {"pentium2_klamath", 50000000, 1.0}, - {"pentium2_klamath", 60000000, 1.0}, - {"pentium2_klamath", 66666666, 1.0}, - {"pentium2_klamath", 75000000, 1.5}, - {"pentium2_klamath", 233333333, 3.5}, - {"pentium2_klamath", 266666666, 4.0}, - {"pentium2_klamath", 300000000, 4.5}, - {"pentium2_deschutes", 50000000, 1.0}, - {"pentium2_deschutes", 60000000, 1.0}, - {"pentium2_deschutes", 66666666, 1.0}, - {"pentium2_deschutes", 75000000, 1.5}, - {"pentium2_deschutes", 266666666, 4.0}, - {"pentium2_deschutes", 300000000, 4.5}, - {"pentium2_deschutes", 333333333, 5.0}, - {NULL, 0, 0} - + {"pentium2_klamath", 50000000, 1.0}, + { "pentium2_klamath", 60000000, 1.0}, + { "pentium2_klamath", 66666666, 1.0}, + { "pentium2_klamath", 75000000, 1.5}, + { "pentium2_klamath", 233333333, 3.5}, + { "pentium2_klamath", 266666666, 4.0}, + { "pentium2_klamath", 300000000, 4.5}, + { "pentium2_deschutes", 50000000, 1.0}, + { "pentium2_deschutes", 60000000, 1.0}, + { "pentium2_deschutes", 66666666, 1.0}, + { "pentium2_deschutes", 75000000, 1.5}, + { "pentium2_deschutes", 266666666, 4.0}, + { "pentium2_deschutes", 300000000, 4.5}, + { "pentium2_deschutes", 333333333, 5.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumII[] = { - {"pentium2_klamath", 50000000, 1.0}, - {"pentium2_klamath", 60000000, 1.0}, - {"pentium2_klamath", 66666666, 1.0}, - {"pentium2_klamath", 75000000, 1.5}, - {"pentium2_klamath", 233333333, 3.5}, - {"pentium2_klamath", 266666666, 4.0}, - {"pentium2_klamath", 300000000, 4.5}, - {"pentium2_deschutes", 50000000, 1.0}, - {"pentium2_deschutes", 60000000, 1.0}, - {"pentium2_deschutes", 66666666, 1.0}, - {"pentium2_deschutes", 75000000, 1.5}, - {"pentium2_deschutes", 266666666, 4.0}, - {"pentium2_deschutes", 300000000, 4.5}, - {"pentium2_deschutes", 333333333, 5.0}, - {"pentium2_deschutes", 350000000, 3.5}, - {"pentium2_deschutes", 400000000, 4.0}, - {"pentium2_deschutes", 450000000, 4.5}, - {NULL, 0, 0} + {"pentium2_klamath", 50000000, 1.0}, + { "pentium2_klamath", 60000000, 1.0}, + { "pentium2_klamath", 66666666, 1.0}, + { "pentium2_klamath", 75000000, 1.5}, + { "pentium2_klamath", 233333333, 3.5}, + { "pentium2_klamath", 266666666, 4.0}, + { "pentium2_klamath", 300000000, 4.5}, + { "pentium2_deschutes", 50000000, 1.0}, + { "pentium2_deschutes", 60000000, 1.0}, + { "pentium2_deschutes", 66666666, 1.0}, + { "pentium2_deschutes", 75000000, 1.5}, + { "pentium2_deschutes", 266666666, 4.0}, + { "pentium2_deschutes", 300000000, 4.5}, + { "pentium2_deschutes", 333333333, 5.0}, + { "pentium2_deschutes", 350000000, 3.5}, + { "pentium2_deschutes", 400000000, 4.0}, + { "pentium2_deschutes", 450000000, 4.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Xeon[] = { - {"pentium2_xeon", 75000000, 1.5}, - {"pentium2_xeon", 100000000, 1.5}, - {"pentium2_xeon", 133333333, 2.0}, - {"pentium2_xeon", 166666666, 2.5}, - {"pentium2_xeon", 400000000, 4.0}, - {"pentium2_xeon", 450000000, 4.5}, - {NULL, 0, 0} + {"pentium2_xeon", 75000000, 1.5}, + { "pentium2_xeon", 100000000, 1.5}, + { "pentium2_xeon", 133333333, 2.0}, + { "pentium2_xeon", 166666666, 2.5}, + { "pentium2_xeon", 400000000, 4.0}, + { "pentium2_xeon", 450000000, 4.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Celeron[] = { - {"celeron_mendocino", 66666666, 1.0}, - {"celeron_mendocino", 100000000, 1.5}, - {"celeron_mendocino", 133333333, 2.0}, - {"celeron_mendocino", 166666666, 2.5}, - {"celeron_mendocino", 300000000, 4.5}, - {"celeron_mendocino", 333333333, 5.0}, - {"celeron_mendocino", 366666666, 5.5}, - {"celeron_mendocino", 400000000, 6.0}, - {"celeron_mendocino", 433333333, 6.5}, - {"celeron_mendocino", 466666666, 7.0}, - {"celeron_mendocino", 500000000, 7.5}, - {"celeron_mendocino", 533333333, 8.0}, - {NULL, 0, 0} + {"celeron_mendocino", 66666666, 1.0}, + { "celeron_mendocino", 100000000, 1.5}, + { "celeron_mendocino", 133333333, 2.0}, + { "celeron_mendocino", 166666666, 2.5}, + { "celeron_mendocino", 300000000, 4.5}, + { "celeron_mendocino", 333333333, 5.0}, + { "celeron_mendocino", 366666666, 5.5}, + { "celeron_mendocino", 400000000, 6.0}, + { "celeron_mendocino", 433333333, 6.5}, + { "celeron_mendocino", 466666666, 7.0}, + { "celeron_mendocino", 500000000, 7.5}, + { "celeron_mendocino", 533333333, 8.0}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_PentiumIID[] = { - {"pentium2_deschutes", 50000000, 1.0}, - {"pentium2_deschutes", 60000000, 1.0}, - {"pentium2_deschutes", 66666666, 1.0}, - {"pentium2_deschutes", 75000000, 1.5}, - {"pentium2_deschutes", 266666666, 4.0}, - {"pentium2_deschutes", 300000000, 4.5}, - {"pentium2_deschutes", 333333333, 5.0}, - {"pentium2_deschutes", 350000000, 3.5}, - {"pentium2_deschutes", 400000000, 4.0}, - {"pentium2_deschutes", 450000000, 4.5}, - {NULL, 0, 0} + {"pentium2_deschutes", 50000000, 1.0}, + { "pentium2_deschutes", 60000000, 1.0}, + { "pentium2_deschutes", 66666666, 1.0}, + { "pentium2_deschutes", 75000000, 1.5}, + { "pentium2_deschutes", 266666666, 4.0}, + { "pentium2_deschutes", 300000000, 4.5}, + { "pentium2_deschutes", 333333333, 5.0}, + { "pentium2_deschutes", 350000000, 3.5}, + { "pentium2_deschutes", 400000000, 4.0}, + { "pentium2_deschutes", 450000000, 4.5}, + { NULL, 0, 0 } }; static const cpu_legacy_table_t cpus_Cyrix3[] = { - {"c3_samuel", 66666666, 1.0}, - {"c3_samuel", 233333333, 3.5}, - {"c3_samuel", 266666666, 4.0}, - {"c3_samuel", 300000000, 4.5}, - {"c3_samuel", 333333333, 5.0}, - {"c3_samuel", 350000000, 3.5}, - {"c3_samuel", 400000000, 4.0}, - {"c3_samuel", 450000000, 4.5}, - {"c3_samuel", 500000000, 5.0}, - {"c3_samuel", 550000000, 5.5}, - {"c3_samuel", 600000000, 6.0}, - {"c3_samuel", 650000000, 6.5}, - {"c3_samuel", 700000000, 7.0}, - {NULL, 0, 0} + {"c3_samuel", 66666666, 1.0}, + { "c3_samuel", 233333333, 3.5}, + { "c3_samuel", 266666666, 4.0}, + { "c3_samuel", 300000000, 4.5}, + { "c3_samuel", 333333333, 5.0}, + { "c3_samuel", 350000000, 3.5}, + { "c3_samuel", 400000000, 4.0}, + { "c3_samuel", 450000000, 4.5}, + { "c3_samuel", 500000000, 5.0}, + { "c3_samuel", 550000000, 5.5}, + { "c3_samuel", 600000000, 6.0}, + { "c3_samuel", 650000000, 6.5}, + { "c3_samuel", 700000000, 7.0}, + { NULL, 0, 0 } }; -static const cpu_legacy_table_t *cputables_8088[4] = {cpus_8088}; -static const cpu_legacy_table_t *cputables_pcjr[4] = {cpus_pcjr}; -static const cpu_legacy_table_t *cputables_europc[4] = {cpus_europc}; -static const cpu_legacy_table_t *cputables_pc1512[4] = {cpus_pc1512}; -static const cpu_legacy_table_t *cputables_8086[4] = {cpus_8086}; -static const cpu_legacy_table_t *cputables_286[4] = {cpus_286}; -static const cpu_legacy_table_t *cputables_ibmat[4] = {cpus_ibmat}; -static const cpu_legacy_table_t *cputables_ps1_m2011[4] = {cpus_ps1_m2011}; -static const cpu_legacy_table_t *cputables_ps2_m30_286_IBM486SLC[4] = {cpus_ps2_m30_286, cpus_IBM486SLC}; -static const cpu_legacy_table_t *cputables_ibmxt286[4] = {cpus_ibmxt286}; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC[4] = {cpus_i386SX, cpus_Am386SX, cpus_486SLC}; -static const cpu_legacy_table_t *cputables_ALiM6117[4] = {cpus_ALiM6117}; -static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC_IBM486SLC[4] = {cpus_i386SX, cpus_Am386SX, cpus_486SLC, cpus_IBM486SLC}; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC[4] = {cpus_i386DX, cpus_Am386DX, cpus_486DLC}; -static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC_IBM486BL[4] = {cpus_i386DX, cpus_Am386DX, cpus_486DLC, cpus_IBM486BL}; -static const cpu_legacy_table_t *cputables_i486_Am486_Cx486[4] = {cpus_i486, cpus_Am486, cpus_Cx486}; -static const cpu_legacy_table_t *cputables_i486S1_Am486S1_Cx486S1[4] = {cpus_i486S1, cpus_Am486S1, cpus_Cx486S1}; -static const cpu_legacy_table_t *cputables_IBM486SLC[4] = {cpus_IBM486SLC}; -static const cpu_legacy_table_t *cputables_i486_PC330[4] = {cpus_i486_PC330}; -static const cpu_legacy_table_t *cputables_STPCDX[4] = {cpus_STPCDX}; -static const cpu_legacy_table_t *cputables_STPCDX2[4] = {cpus_STPCDX2}; -static const cpu_legacy_table_t *cputables_Pentium5V[4] = {cpus_Pentium5V}; -static const cpu_legacy_table_t *cputables_PentiumS5_WinChip_K5[4] = {cpus_PentiumS5, cpus_WinChip, cpus_K5}; -static const cpu_legacy_table_t *cputables_Pentium3V_WinChip_K5_6x863V[4] = {cpus_Pentium3V, cpus_WinChip, cpus_K5, cpus_6x863V}; -static const cpu_legacy_table_t *cputables_Pentium3V_K5[4] = {cpus_Pentium3V, cpus_K5}; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_K56_6x86[4] = {cpus_Pentium, cpus_WinChip, cpus_K56, cpus_6x86}; -static const cpu_legacy_table_t *cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7[4] = {cpus_Pentium, cpus_WinChip_SS7, cpus_K56_SS7, cpus_6x86SS7}; -static const cpu_legacy_table_t *cputables_PentiumPro[4] = {cpus_PentiumPro}; -static const cpu_legacy_table_t *cputables_PentiumII66[4] = {cpus_PentiumII66}; -static const cpu_legacy_table_t *cputables_PentiumII_Celeron_Cyrix3[4] = {cpus_PentiumII, cpus_Celeron, cpus_Cyrix3}; -static const cpu_legacy_table_t *cputables_Xeon[4] = {cpus_Xeon}; -static const cpu_legacy_table_t *cputables_Celeron_Cyrix3[4] = {cpus_Celeron, cpus_Cyrix3}; -static const cpu_legacy_table_t *cputables_Celeron[4] = {cpus_Celeron}; -static const cpu_legacy_table_t *cputables_PentiumIID_Celeron[4] = {cpus_PentiumIID, cpus_Celeron}; +static const cpu_legacy_table_t *cputables_8088[4] = { cpus_8088 }; +static const cpu_legacy_table_t *cputables_pcjr[4] = { cpus_pcjr }; +static const cpu_legacy_table_t *cputables_europc[4] = { cpus_europc }; +static const cpu_legacy_table_t *cputables_pc1512[4] = { cpus_pc1512 }; +static const cpu_legacy_table_t *cputables_8086[4] = { cpus_8086 }; +static const cpu_legacy_table_t *cputables_286[4] = { cpus_286 }; +static const cpu_legacy_table_t *cputables_ibmat[4] = { cpus_ibmat }; +static const cpu_legacy_table_t *cputables_ps1_m2011[4] = { cpus_ps1_m2011 }; +static const cpu_legacy_table_t *cputables_ps2_m30_286_IBM486SLC[4] = { cpus_ps2_m30_286, cpus_IBM486SLC }; +static const cpu_legacy_table_t *cputables_ibmxt286[4] = { cpus_ibmxt286 }; +static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC }; +static const cpu_legacy_table_t *cputables_ALiM6117[4] = { cpus_ALiM6117 }; +static const cpu_legacy_table_t *cputables_i386SX_Am386SX_486SLC_IBM486SLC[4] = { cpus_i386SX, cpus_Am386SX, cpus_486SLC, cpus_IBM486SLC }; +static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC }; +static const cpu_legacy_table_t *cputables_i386DX_Am386DX_486DLC_IBM486BL[4] = { cpus_i386DX, cpus_Am386DX, cpus_486DLC, cpus_IBM486BL }; +static const cpu_legacy_table_t *cputables_i486_Am486_Cx486[4] = { cpus_i486, cpus_Am486, cpus_Cx486 }; +static const cpu_legacy_table_t *cputables_i486S1_Am486S1_Cx486S1[4] = { cpus_i486S1, cpus_Am486S1, cpus_Cx486S1 }; +static const cpu_legacy_table_t *cputables_IBM486SLC[4] = { cpus_IBM486SLC }; +static const cpu_legacy_table_t *cputables_i486_PC330[4] = { cpus_i486_PC330 }; +static const cpu_legacy_table_t *cputables_STPCDX[4] = { cpus_STPCDX }; +static const cpu_legacy_table_t *cputables_STPCDX2[4] = { cpus_STPCDX2 }; +static const cpu_legacy_table_t *cputables_Pentium5V[4] = { cpus_Pentium5V }; +static const cpu_legacy_table_t *cputables_PentiumS5_WinChip_K5[4] = { cpus_PentiumS5, cpus_WinChip, cpus_K5 }; +static const cpu_legacy_table_t *cputables_Pentium3V_WinChip_K5_6x863V[4] = { cpus_Pentium3V, cpus_WinChip, cpus_K5, cpus_6x863V }; +static const cpu_legacy_table_t *cputables_Pentium3V_K5[4] = { cpus_Pentium3V, cpus_K5 }; +static const cpu_legacy_table_t *cputables_Pentium_WinChip_K56_6x86[4] = { cpus_Pentium, cpus_WinChip, cpus_K56, cpus_6x86 }; +static const cpu_legacy_table_t *cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7[4] = { cpus_Pentium, cpus_WinChip_SS7, cpus_K56_SS7, cpus_6x86SS7 }; +static const cpu_legacy_table_t *cputables_PentiumPro[4] = { cpus_PentiumPro }; +static const cpu_legacy_table_t *cputables_PentiumII66[4] = { cpus_PentiumII66 }; +static const cpu_legacy_table_t *cputables_PentiumII_Celeron_Cyrix3[4] = { cpus_PentiumII, cpus_Celeron, cpus_Cyrix3 }; +static const cpu_legacy_table_t *cputables_Xeon[4] = { cpus_Xeon }; +static const cpu_legacy_table_t *cputables_Celeron_Cyrix3[4] = { cpus_Celeron, cpus_Cyrix3 }; +static const cpu_legacy_table_t *cputables_Celeron[4] = { cpus_Celeron }; +static const cpu_legacy_table_t *cputables_PentiumIID_Celeron[4] = { cpus_PentiumIID, cpus_Celeron }; const cpu_legacy_machine_t cpu_legacy_table[] = { - {"ibmpc", cputables_8088}, - {"ibmpc82", cputables_8088}, - {"ibmpcjr", cputables_pcjr}, - {"ibmxt", cputables_8088}, - {"ibmxt86", cputables_8088}, - {"americxt", cputables_8088}, - {"amixt", cputables_8088}, - {"portable", cputables_8088}, - {"dtk", cputables_8088}, - {"genxt", cputables_8088}, - {"jukopc", cputables_8088}, - {"openxt", cputables_8088}, - {"pxxt", cputables_8088}, - {"europc", cputables_europc}, - {"tandy", cputables_europc}, - {"tandy1000hx", cputables_europc}, - {"t1000", cputables_8088}, - {"ltxt", cputables_8088}, - {"xi8088", cputables_8088}, - {"zdsupers", cputables_8088}, - {"pc1512", cputables_pc1512}, - {"pc1640", cputables_8086}, - {"pc2086", cputables_8086}, - {"pc3086", cputables_8086}, - {"pc200", cputables_8086}, - {"ppc512", cputables_8086}, - {"deskpro", cputables_8086}, - {"m24", cputables_8086}, - {"iskra3104", cputables_8086}, - {"tandy1000sl2", cputables_8086}, - {"t1200", cputables_8086}, - {"lxt3", cputables_8086}, - {"hed919", cputables_286}, - {"ibmat", cputables_ibmat}, - {"ibmps1es", cputables_ps1_m2011}, - {"ibmps2_m30_286", cputables_ps2_m30_286_IBM486SLC}, - {"ibmxt286", cputables_ibmxt286}, - {"ibmatami", cputables_ibmat}, - {"cmdpc30", cputables_286}, - {"portableii", cputables_286}, - {"portableiii", cputables_286}, - {"mr286", cputables_286}, - {"open_at", cputables_286}, - {"ibmatpx", cputables_ibmat}, - {"ibmatquadtel", cputables_ibmat}, - {"siemens", cputables_286}, - {"t3100e", cputables_286}, - {"quadt286", cputables_286}, - {"tg286m", cputables_286}, - {"ami286", cputables_286}, - {"px286", cputables_286}, - {"award286", cputables_286}, - {"gw286ct", cputables_286}, - {"gdc212m", cputables_286}, - {"super286tr", cputables_286}, - {"spc4200p", cputables_286}, - {"spc4216p", cputables_286}, - {"deskmaster286", cputables_286}, - {"ibmps2_m50", cputables_ps2_m30_286_IBM486SLC}, - {"ibmps1_2121", cputables_i386SX_Am386SX_486SLC}, - {"ibmps1_2121_isa", cputables_i386SX_Am386SX_486SLC}, - {"arb1375", cputables_ALiM6117}, - {"pja511m", cputables_ALiM6117}, - {"ama932j", cputables_i386SX_Am386SX_486SLC}, - {"adi386sx", cputables_i386SX_Am386SX_486SLC}, - {"shuttle386sx", cputables_i386SX_Am386SX_486SLC}, - {"dtk386", cputables_i386SX_Am386SX_486SLC}, - {"awardsx", cputables_i386SX_Am386SX_486SLC}, - {"cmdsl386sx25", cputables_i386SX_Am386SX_486SLC}, - {"kmxc02", cputables_i386SX_Am386SX_486SLC}, - {"megapc", cputables_i386SX_Am386SX_486SLC}, - {"ibmps2_m55sx", cputables_i386SX_Am386SX_486SLC_IBM486SLC}, - {"acc386", cputables_i386DX_Am386DX_486DLC}, - {"ecs386", cputables_i386DX_Am386DX_486DLC}, - {"portableiii386", cputables_i386DX_Am386DX_486DLC}, - {"micronics386", cputables_i386DX_Am386DX_486DLC}, - {"asus386", cputables_i386DX_Am386DX_486DLC}, - {"ustechnologies386", cputables_i386DX_Am386DX_486DLC}, - {"award386dx", cputables_i386DX_Am386DX_486DLC}, - {"ibmps2_m70_type3", cputables_i386DX_Am386DX_486DLC_IBM486BL}, - {"ibmps2_m80", cputables_i386DX_Am386DX_486DLC_IBM486BL}, - {"pb410a", cputables_i486_Am486_Cx486}, - {"acera1g", cputables_i486_Am486_Cx486}, - {"win486", cputables_i486_Am486_Cx486}, - {"ali1429", cputables_i486S1_Am486S1_Cx486S1}, - {"cs4031", cputables_i486S1_Am486S1_Cx486S1}, - {"rycleopardlx", cputables_IBM486SLC}, - {"award486", cputables_i486S1_Am486S1_Cx486S1}, - {"ami486", cputables_i486S1_Am486S1_Cx486S1}, - {"mr486", cputables_i486_Am486_Cx486}, - {"pc330_6571", cputables_i486_PC330}, - {"403tg", cputables_i486_Am486_Cx486}, - {"sis401", cputables_i486_Am486_Cx486}, - {"valuepoint433", cputables_i486_Am486_Cx486}, - {"ami471", cputables_i486_Am486_Cx486}, - {"win471", cputables_i486_Am486_Cx486}, - {"vi15g", cputables_i486_Am486_Cx486}, - {"vli486sv2g", cputables_i486_Am486_Cx486}, - {"dtk486", cputables_i486_Am486_Cx486}, - {"px471", cputables_i486_Am486_Cx486}, - {"486vchd", cputables_i486S1_Am486S1_Cx486S1}, - {"ibmps1_2133", cputables_i486S1_Am486S1_Cx486S1}, - {"vect486vl", cputables_i486S1_Am486S1_Cx486S1}, - {"ibmps2_m70_type4", cputables_i486S1_Am486S1_Cx486S1}, - {"abpb4", cputables_i486_Am486_Cx486}, - {"486ap4", cputables_i486_Am486_Cx486}, - {"486sp3g", cputables_i486_Am486_Cx486}, - {"alfredo", cputables_i486_Am486_Cx486}, - {"ls486e", cputables_i486_Am486_Cx486}, - {"m4li", cputables_i486_Am486_Cx486}, - {"r418", cputables_i486_Am486_Cx486}, - {"4sa2", cputables_i486_Am486_Cx486}, - {"4dps", cputables_i486_Am486_Cx486}, - {"itoxstar", cputables_STPCDX}, - {"arb1479", cputables_STPCDX2}, - {"pcm9340", cputables_STPCDX2}, - {"pcm5330", cputables_STPCDX2}, - {"486vipio2", cputables_i486_Am486_Cx486}, - {"p5mp3", cputables_Pentium5V}, - {"dellxp60", cputables_Pentium5V}, - {"opti560l", cputables_Pentium5V}, - {"ambradp60", cputables_Pentium5V}, - {"valuepointp60", cputables_Pentium5V}, - {"revenge", cputables_Pentium5V}, - {"586mc1", cputables_Pentium5V}, - {"pb520r", cputables_Pentium5V}, - {"excalibur", cputables_Pentium5V}, - {"plato", cputables_PentiumS5_WinChip_K5}, - {"ambradp90", cputables_PentiumS5_WinChip_K5}, - {"430nx", cputables_PentiumS5_WinChip_K5}, - {"acerv30", cputables_PentiumS5_WinChip_K5}, - {"apollo", cputables_PentiumS5_WinChip_K5}, - {"vectra54", cputables_PentiumS5_WinChip_K5}, - {"zappa", cputables_PentiumS5_WinChip_K5}, - {"powermate_v", cputables_PentiumS5_WinChip_K5}, - {"mb500n", cputables_PentiumS5_WinChip_K5}, - {"p54tp4xe", cputables_Pentium3V_WinChip_K5_6x863V}, - {"mr586", cputables_Pentium3V_WinChip_K5_6x863V}, - {"gw2katx", cputables_Pentium3V_WinChip_K5_6x863V}, - {"thor", cputables_Pentium3V_WinChip_K5_6x863V}, - {"mrthor", cputables_Pentium3V_WinChip_K5_6x863V}, - {"endeavor", cputables_Pentium3V_WinChip_K5_6x863V}, - {"pb640", cputables_Pentium3V_WinChip_K5_6x863V}, - {"chariot", cputables_Pentium3V_K5}, - {"acerm3a", cputables_Pentium3V_WinChip_K5_6x863V}, - {"ap53", cputables_Pentium3V_WinChip_K5_6x863V}, - {"8500tuc", cputables_Pentium3V_WinChip_K5_6x863V}, - {"p55t2s", cputables_Pentium3V_WinChip_K5_6x863V}, - {"acerv35n", cputables_Pentium_WinChip_K56_6x86}, - {"p55t2p4", cputables_Pentium_WinChip_K56_6x86}, - {"m7shi", cputables_Pentium_WinChip_K56_6x86}, - {"tc430hx", cputables_Pentium_WinChip_K56_6x86}, - {"equium5200", cputables_Pentium_WinChip_K56_6x86}, - {"pcv240", cputables_Pentium_WinChip_K56_6x86}, - {"p65up5_cp55t2d", cputables_Pentium_WinChip_K56_6x86}, - {"p55tvp4", cputables_Pentium_WinChip_K56_6x86}, - {"8500tvxa", cputables_Pentium_WinChip_K56_6x86}, - {"presario4500", cputables_Pentium_WinChip_K56_6x86}, - {"p55va", cputables_Pentium_WinChip_K56_6x86}, - {"gw2kte", cputables_Pentium_WinChip_K56_6x86}, - {"brio80xx", cputables_Pentium_WinChip_K56_6x86}, - {"pb680", cputables_Pentium_WinChip_K56_6x86}, - {"430vx", cputables_Pentium_WinChip_K56_6x86}, - {"nupro592", cputables_Pentium_WinChip_K56_6x86}, - {"tx97", cputables_Pentium_WinChip_K56_6x86}, - {"an430tx", cputables_Pentium_WinChip_K56_6x86}, - {"ym430tx", cputables_Pentium_WinChip_K56_6x86}, - {"mb540n", cputables_Pentium_WinChip_K56_6x86}, - {"p5mms98", cputables_Pentium_WinChip_K56_6x86}, - {"ficva502", cputables_Pentium_WinChip_K56_6x86}, - {"ficpa2012", cputables_Pentium_WinChip_K56_6x86}, - {"ax59pro", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - {"ficva503p", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - {"ficva503a", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, - {"v60n", cputables_PentiumPro}, - {"p65up5_cp6nd", cputables_PentiumPro}, - {"8600ttc", cputables_PentiumPro}, - {"686nx", cputables_PentiumPro}, - {"ap440fx", cputables_PentiumPro}, - {"vs440fx", cputables_PentiumPro}, - {"m6mi", cputables_PentiumPro}, - {"mb600n", cputables_PentiumPro}, - {"p65up5_cpknd", cputables_PentiumII66}, - {"kn97", cputables_PentiumII66}, - {"lx6", cputables_PentiumII66}, - {"spitfire", cputables_PentiumII66}, - {"p6i440e2", cputables_PentiumII66}, - {"p2bls", cputables_PentiumII_Celeron_Cyrix3}, - {"p3bf", cputables_PentiumII_Celeron_Cyrix3}, - {"bf6", cputables_PentiumII_Celeron_Cyrix3}, - {"ax6bc", cputables_PentiumII_Celeron_Cyrix3}, - {"atc6310bxii", cputables_PentiumII_Celeron_Cyrix3}, - {"686bx", cputables_PentiumII_Celeron_Cyrix3}, - {"tsunamiatx", cputables_PentiumII_Celeron_Cyrix3}, - {"p6sba", cputables_PentiumII_Celeron_Cyrix3}, - {"ergox365", cputables_PentiumII_Celeron_Cyrix3}, - {"ficka6130", cputables_PentiumII_Celeron_Cyrix3}, - {"6gxu", cputables_Xeon}, - {"fw6400gx", cputables_Xeon}, - {"s2dge", cputables_Xeon}, - {"s370slm", cputables_Celeron_Cyrix3}, - {"awo671r", cputables_Celeron_Cyrix3}, - {"cubx", cputables_Celeron_Cyrix3}, - {"atc7020bxii", cputables_Celeron_Cyrix3}, - {"ambx133", cputables_Celeron_Cyrix3}, - {"trinity371", cputables_Celeron}, - {"63a", cputables_Celeron_Cyrix3}, - {"apas3", cputables_Celeron_Cyrix3}, - {"wcf681", cputables_Celeron_Cyrix3}, - {"6via90ap", cputables_Celeron_Cyrix3}, - {"p6bap", cputables_Celeron_Cyrix3}, - {"603tcf", cputables_Celeron_Cyrix3}, - {"vpc2007", cputables_PentiumIID_Celeron}, - {NULL, NULL} + {"ibmpc", cputables_8088 }, + { "ibmpc82", cputables_8088 }, + { "ibmpcjr", cputables_pcjr }, + { "ibmxt", cputables_8088 }, + { "ibmxt86", cputables_8088 }, + { "americxt", cputables_8088 }, + { "amixt", cputables_8088 }, + { "portable", cputables_8088 }, + { "dtk", cputables_8088 }, + { "genxt", cputables_8088 }, + { "jukopc", cputables_8088 }, + { "openxt", cputables_8088 }, + { "pxxt", cputables_8088 }, + { "europc", cputables_europc }, + { "tandy", cputables_europc }, + { "tandy1000hx", cputables_europc }, + { "t1000", cputables_8088 }, + { "ltxt", cputables_8088 }, + { "xi8088", cputables_8088 }, + { "zdsupers", cputables_8088 }, + { "pc1512", cputables_pc1512 }, + { "pc1640", cputables_8086 }, + { "pc2086", cputables_8086 }, + { "pc3086", cputables_8086 }, + { "pc200", cputables_8086 }, + { "ppc512", cputables_8086 }, + { "deskpro", cputables_8086 }, + { "m24", cputables_8086 }, + { "iskra3104", cputables_8086 }, + { "tandy1000sl2", cputables_8086 }, + { "t1200", cputables_8086 }, + { "lxt3", cputables_8086 }, + { "hed919", cputables_286 }, + { "ibmat", cputables_ibmat }, + { "ibmps1es", cputables_ps1_m2011 }, + { "ibmps2_m30_286", cputables_ps2_m30_286_IBM486SLC }, + { "ibmxt286", cputables_ibmxt286 }, + { "ibmatami", cputables_ibmat }, + { "cmdpc30", cputables_286 }, + { "portableii", cputables_286 }, + { "portableiii", cputables_286 }, + { "mr286", cputables_286 }, + { "open_at", cputables_286 }, + { "ibmatpx", cputables_ibmat }, + { "ibmatquadtel", cputables_ibmat }, + { "siemens", cputables_286 }, + { "t3100e", cputables_286 }, + { "quadt286", cputables_286 }, + { "tg286m", cputables_286 }, + { "ami286", cputables_286 }, + { "px286", cputables_286 }, + { "award286", cputables_286 }, + { "gw286ct", cputables_286 }, + { "gdc212m", cputables_286 }, + { "super286tr", cputables_286 }, + { "spc4200p", cputables_286 }, + { "spc4216p", cputables_286 }, + { "deskmaster286", cputables_286 }, + { "ibmps2_m50", cputables_ps2_m30_286_IBM486SLC }, + { "ibmps1_2121", cputables_i386SX_Am386SX_486SLC }, + { "ibmps1_2121_isa", cputables_i386SX_Am386SX_486SLC }, + { "arb1375", cputables_ALiM6117 }, + { "pja511m", cputables_ALiM6117 }, + { "ama932j", cputables_i386SX_Am386SX_486SLC }, + { "adi386sx", cputables_i386SX_Am386SX_486SLC }, + { "shuttle386sx", cputables_i386SX_Am386SX_486SLC }, + { "dtk386", cputables_i386SX_Am386SX_486SLC }, + { "awardsx", cputables_i386SX_Am386SX_486SLC }, + { "cmdsl386sx25", cputables_i386SX_Am386SX_486SLC }, + { "kmxc02", cputables_i386SX_Am386SX_486SLC }, + { "megapc", cputables_i386SX_Am386SX_486SLC }, + { "ibmps2_m55sx", cputables_i386SX_Am386SX_486SLC_IBM486SLC }, + { "acc386", cputables_i386DX_Am386DX_486DLC }, + { "ecs386", cputables_i386DX_Am386DX_486DLC }, + { "portableiii386", cputables_i386DX_Am386DX_486DLC }, + { "micronics386", cputables_i386DX_Am386DX_486DLC }, + { "asus386", cputables_i386DX_Am386DX_486DLC }, + { "ustechnologies386", cputables_i386DX_Am386DX_486DLC }, + { "award386dx", cputables_i386DX_Am386DX_486DLC }, + { "ibmps2_m70_type3", cputables_i386DX_Am386DX_486DLC_IBM486BL }, + { "ibmps2_m80", cputables_i386DX_Am386DX_486DLC_IBM486BL }, + { "pb410a", cputables_i486_Am486_Cx486 }, + { "acera1g", cputables_i486_Am486_Cx486 }, + { "win486", cputables_i486_Am486_Cx486 }, + { "ali1429", cputables_i486S1_Am486S1_Cx486S1 }, + { "cs4031", cputables_i486S1_Am486S1_Cx486S1 }, + { "rycleopardlx", cputables_IBM486SLC }, + { "award486", cputables_i486S1_Am486S1_Cx486S1 }, + { "ami486", cputables_i486S1_Am486S1_Cx486S1 }, + { "mr486", cputables_i486_Am486_Cx486 }, + { "pc330_6571", cputables_i486_PC330 }, + { "403tg", cputables_i486_Am486_Cx486 }, + { "sis401", cputables_i486_Am486_Cx486 }, + { "valuepoint433", cputables_i486_Am486_Cx486 }, + { "ami471", cputables_i486_Am486_Cx486 }, + { "win471", cputables_i486_Am486_Cx486 }, + { "vi15g", cputables_i486_Am486_Cx486 }, + { "vli486sv2g", cputables_i486_Am486_Cx486 }, + { "dtk486", cputables_i486_Am486_Cx486 }, + { "px471", cputables_i486_Am486_Cx486 }, + { "486vchd", cputables_i486S1_Am486S1_Cx486S1 }, + { "ibmps1_2133", cputables_i486S1_Am486S1_Cx486S1 }, + { "vect486vl", cputables_i486S1_Am486S1_Cx486S1 }, + { "ibmps2_m70_type4", cputables_i486S1_Am486S1_Cx486S1 }, + { "abpb4", cputables_i486_Am486_Cx486 }, + { "486ap4", cputables_i486_Am486_Cx486 }, + { "486sp3g", cputables_i486_Am486_Cx486 }, + { "alfredo", cputables_i486_Am486_Cx486 }, + { "ls486e", cputables_i486_Am486_Cx486 }, + { "m4li", cputables_i486_Am486_Cx486 }, + { "r418", cputables_i486_Am486_Cx486 }, + { "4sa2", cputables_i486_Am486_Cx486 }, + { "4dps", cputables_i486_Am486_Cx486 }, + { "itoxstar", cputables_STPCDX }, + { "arb1479", cputables_STPCDX2 }, + { "pcm9340", cputables_STPCDX2 }, + { "pcm5330", cputables_STPCDX2 }, + { "486vipio2", cputables_i486_Am486_Cx486 }, + { "p5mp3", cputables_Pentium5V }, + { "dellxp60", cputables_Pentium5V }, + { "opti560l", cputables_Pentium5V }, + { "ambradp60", cputables_Pentium5V }, + { "valuepointp60", cputables_Pentium5V }, + { "revenge", cputables_Pentium5V }, + { "586mc1", cputables_Pentium5V }, + { "pb520r", cputables_Pentium5V }, + { "excalibur", cputables_Pentium5V }, + { "plato", cputables_PentiumS5_WinChip_K5 }, + { "ambradp90", cputables_PentiumS5_WinChip_K5 }, + { "430nx", cputables_PentiumS5_WinChip_K5 }, + { "acerv30", cputables_PentiumS5_WinChip_K5 }, + { "apollo", cputables_PentiumS5_WinChip_K5 }, + { "vectra54", cputables_PentiumS5_WinChip_K5 }, + { "zappa", cputables_PentiumS5_WinChip_K5 }, + { "powermate_v", cputables_PentiumS5_WinChip_K5 }, + { "mb500n", cputables_PentiumS5_WinChip_K5 }, + { "p54tp4xe", cputables_Pentium3V_WinChip_K5_6x863V }, + { "mr586", cputables_Pentium3V_WinChip_K5_6x863V }, + { "gw2katx", cputables_Pentium3V_WinChip_K5_6x863V }, + { "thor", cputables_Pentium3V_WinChip_K5_6x863V }, + { "mrthor", cputables_Pentium3V_WinChip_K5_6x863V }, + { "endeavor", cputables_Pentium3V_WinChip_K5_6x863V }, + { "pb640", cputables_Pentium3V_WinChip_K5_6x863V }, + { "chariot", cputables_Pentium3V_K5 }, + { "acerm3a", cputables_Pentium3V_WinChip_K5_6x863V }, + { "ap53", cputables_Pentium3V_WinChip_K5_6x863V }, + { "8500tuc", cputables_Pentium3V_WinChip_K5_6x863V }, + { "p55t2s", cputables_Pentium3V_WinChip_K5_6x863V }, + { "acerv35n", cputables_Pentium_WinChip_K56_6x86 }, + { "p55t2p4", cputables_Pentium_WinChip_K56_6x86 }, + { "m7shi", cputables_Pentium_WinChip_K56_6x86 }, + { "tc430hx", cputables_Pentium_WinChip_K56_6x86 }, + { "equium5200", cputables_Pentium_WinChip_K56_6x86 }, + { "pcv240", cputables_Pentium_WinChip_K56_6x86 }, + { "p65up5_cp55t2d", cputables_Pentium_WinChip_K56_6x86 }, + { "p55tvp4", cputables_Pentium_WinChip_K56_6x86 }, + { "8500tvxa", cputables_Pentium_WinChip_K56_6x86 }, + { "presario4500", cputables_Pentium_WinChip_K56_6x86 }, + { "p55va", cputables_Pentium_WinChip_K56_6x86 }, + { "gw2kte", cputables_Pentium_WinChip_K56_6x86 }, + { "brio80xx", cputables_Pentium_WinChip_K56_6x86 }, + { "pb680", cputables_Pentium_WinChip_K56_6x86 }, + { "430vx", cputables_Pentium_WinChip_K56_6x86 }, + { "nupro592", cputables_Pentium_WinChip_K56_6x86 }, + { "tx97", cputables_Pentium_WinChip_K56_6x86 }, + { "an430tx", cputables_Pentium_WinChip_K56_6x86 }, + { "ym430tx", cputables_Pentium_WinChip_K56_6x86 }, + { "mb540n", cputables_Pentium_WinChip_K56_6x86 }, + { "p5mms98", cputables_Pentium_WinChip_K56_6x86 }, + { "ficva502", cputables_Pentium_WinChip_K56_6x86 }, + { "ficpa2012", cputables_Pentium_WinChip_K56_6x86 }, + { "ax59pro", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, + { "ficva503p", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, + { "ficva503a", cputables_Pentium_WinChip_SS7_K56_SS7_6x86SS7}, + { "v60n", cputables_PentiumPro }, + { "p65up5_cp6nd", cputables_PentiumPro }, + { "8600ttc", cputables_PentiumPro }, + { "686nx", cputables_PentiumPro }, + { "ap440fx", cputables_PentiumPro }, + { "vs440fx", cputables_PentiumPro }, + { "m6mi", cputables_PentiumPro }, + { "mb600n", cputables_PentiumPro }, + { "p65up5_cpknd", cputables_PentiumII66 }, + { "kn97", cputables_PentiumII66 }, + { "lx6", cputables_PentiumII66 }, + { "spitfire", cputables_PentiumII66 }, + { "p6i440e2", cputables_PentiumII66 }, + { "p2bls", cputables_PentiumII_Celeron_Cyrix3 }, + { "p3bf", cputables_PentiumII_Celeron_Cyrix3 }, + { "bf6", cputables_PentiumII_Celeron_Cyrix3 }, + { "ax6bc", cputables_PentiumII_Celeron_Cyrix3 }, + { "atc6310bxii", cputables_PentiumII_Celeron_Cyrix3 }, + { "686bx", cputables_PentiumII_Celeron_Cyrix3 }, + { "tsunamiatx", cputables_PentiumII_Celeron_Cyrix3 }, + { "p6sba", cputables_PentiumII_Celeron_Cyrix3 }, + { "ergox365", cputables_PentiumII_Celeron_Cyrix3 }, + { "ficka6130", cputables_PentiumII_Celeron_Cyrix3 }, + { "6gxu", cputables_Xeon }, + { "fw6400gx", cputables_Xeon }, + { "s2dge", cputables_Xeon }, + { "s370slm", cputables_Celeron_Cyrix3 }, + { "awo671r", cputables_Celeron_Cyrix3 }, + { "cubx", cputables_Celeron_Cyrix3 }, + { "atc7020bxii", cputables_Celeron_Cyrix3 }, + { "ambx133", cputables_Celeron_Cyrix3 }, + { "trinity371", cputables_Celeron }, + { "63a", cputables_Celeron_Cyrix3 }, + { "apas3", cputables_Celeron_Cyrix3 }, + { "wcf681", cputables_Celeron_Cyrix3 }, + { "6via90ap", cputables_Celeron_Cyrix3 }, + { "p6bap", cputables_Celeron_Cyrix3 }, + { "603tcf", cputables_Celeron_Cyrix3 }, + { "vpc2007", cputables_PentiumIID_Celeron }, + { NULL, NULL } }; diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index 06b48552d..eb7a35ace 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -378,9 +378,8 @@ opPMULHRW(uint32_t fetchdat) return 0; } -const OpFn OP_TABLE(3DNOW)[256] = -{ -// clang-format off +const OpFn OP_TABLE(3DNOW)[256] = { + // clang-format off /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FD, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2ID, ILLEGAL, ILLEGAL, @@ -401,12 +400,11 @@ const OpFn OP_TABLE(3DNOW)[256] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(3DNOWE)[256] = -{ -// clang-format off +const OpFn OP_TABLE(3DNOWE)[256] = { + // clang-format off /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPI2FW, opPI2FD, ILLEGAL, ILLEGAL, /*10*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, opPF2IW, opPF2ID, ILLEGAL, ILLEGAL, @@ -427,7 +425,7 @@ const OpFn OP_TABLE(3DNOWE)[256] = /*d0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*e0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*f0*/ ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, -// clang-format on + // clang-format on }; static int diff --git a/src/cpu/x86_ops_jump.h b/src/cpu/x86_ops_jump.h index f9093084c..a1503a75e 100644 --- a/src/cpu/x86_ops_jump.h +++ b/src/cpu/x86_ops_jump.h @@ -88,8 +88,7 @@ opJ(LE) opJ(NLE) // clang-format on - - static int opLOOPNE_w(uint32_t fetchdat) + static int opLOOPNE_w(uint32_t fetchdat) { int8_t offset = (int8_t) getbytef(); CX--; diff --git a/src/cpu/x86_ops_prefix.h b/src/cpu/x86_ops_prefix.h index 5edb3dbea..eba59c17a 100644 --- a/src/cpu/x86_ops_prefix.h +++ b/src/cpu/x86_ops_prefix.h @@ -90,7 +90,7 @@ op_seg(GS_REPNE, cpu_state.seg_gs, x86_opcodes_REPNE, x86_opcodes) op_seg(SS_REPNE, cpu_state.seg_ss, x86_opcodes_REPNE, x86_opcodes) // clang-format on - static int op_66(uint32_t fetchdat) /*Data size select*/ + static int op_66(uint32_t fetchdat) /*Data size select*/ { fetchdat = fastreadl(cs + cpu_state.pc); if (cpu_state.abrt) diff --git a/src/cpu/x86_ops_stack.h b/src/cpu/x86_ops_stack.h index 374dad9f4..8217a9e5a 100644 --- a/src/cpu/x86_ops_stack.h +++ b/src/cpu/x86_ops_stack.h @@ -188,28 +188,28 @@ opPOPA_w(uint32_t fetchdat) static int opPOPA_l(uint32_t fetchdat) { - if (stack32) { - EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; - ESP += 32; - } else { - EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; - ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; - EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; - EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; - ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; - EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; - SP += 32; - } - CLOCK_CYCLES((is486) ? 9 : 24); - PREFETCH_RUN(24, 1, -1, 0,7,0,0, 0); - return 0; + if (stack32) { + EDI = readmeml(ss, ESP); if (cpu_state.abrt) return 1; + ESI = readmeml(ss, ESP + 4); if (cpu_state.abrt) return 1; + EBP = readmeml(ss, ESP + 8); if (cpu_state.abrt) return 1; + EBX = readmeml(ss, ESP + 16); if (cpu_state.abrt) return 1; + EDX = readmeml(ss, ESP + 20); if (cpu_state.abrt) return 1; + ECX = readmeml(ss, ESP + 24); if (cpu_state.abrt) return 1; + EAX = readmeml(ss, ESP + 28); if (cpu_state.abrt) return 1; + ESP += 32; + } else { + EDI = readmeml(ss, ((SP) & 0xFFFF)); if (cpu_state.abrt) return 1; + ESI = readmeml(ss, ((SP + 4) & 0xFFFF)); if (cpu_state.abrt) return 1; + EBP = readmeml(ss, ((SP + 8) & 0xFFFF)); if (cpu_state.abrt) return 1; + EBX = readmeml(ss, ((SP + 16) & 0xFFFF)); if (cpu_state.abrt) return 1; + EDX = readmeml(ss, ((SP + 20) & 0xFFFF)); if (cpu_state.abrt) return 1; + ECX = readmeml(ss, ((SP + 24) & 0xFFFF)); if (cpu_state.abrt) return 1; + EAX = readmeml(ss, ((SP + 28) & 0xFFFF)); if (cpu_state.abrt) return 1; + SP += 32; + } + CLOCK_CYCLES((is486) ? 9 : 24); + PREFETCH_RUN(24, 1, -1, 0, 7, 0, 0, 0); + return 0; } static int diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index e8573bfa6..ce4a4becc 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -526,19 +526,17 @@ FPU_ILLEGAL_a32(uint32_t fetchdat) #define ILLEGAL_a16 FPU_ILLEGAL_a16 #ifdef FPU_8087 -const OpFn OP_TABLE(fpu_8087_d8)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_d8)[32] = { + // clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_d9)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_d9)[256] = { + // clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -574,12 +572,11 @@ const OpFn OP_TABLE(fpu_8087_d9)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, ILLEGAL_a16, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, ILLEGAL_a16, opFRNDINT, opFSCALE, ILLEGAL_a16, ILLEGAL_a16 -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_da)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_da)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -615,12 +612,11 @@ const OpFn OP_TABLE(fpu_8087_da)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_db)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_db)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -656,22 +652,20 @@ const OpFn OP_TABLE(fpu_8087_db)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_dc)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_dc)[32] = { + // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_dd)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_dd)[256] = { + // clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -707,12 +701,11 @@ const OpFn OP_TABLE(fpu_8087_dd)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_de)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_de)[256] = { + // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -748,12 +741,11 @@ const OpFn OP_TABLE(fpu_8087_de)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_8087_df)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_8087_df)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -789,34 +781,31 @@ const OpFn OP_TABLE(fpu_8087_df)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; #else # define ILLEGAL_a32 FPU_ILLEGAL_a32 -const OpFn OP_TABLE(fpu_d8_a16)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_d8_a16)[32] = { + // clang-format off opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_d8_a32)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_d8_a32)[32] = { + // clang-format off opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADDs_a32, opFMULs_a32, opFCOMs_a32, opFCOMPs_a32, opFSUBs_a32, opFSUBRs_a32, opFDIVs_a32, opFDIVRs_a32, opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_d9_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_d9_a16)[256] = { + // clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -852,12 +841,11 @@ const OpFn OP_TABLE(fpu_287_d9_a16)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_d9_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_d9_a32)[256] = { + // clang-format off opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, @@ -893,12 +881,11 @@ const OpFn OP_TABLE(fpu_287_d9_a32)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_d9_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_d9_a16)[256] = { + // clang-format off opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, @@ -934,12 +921,11 @@ const OpFn OP_TABLE(fpu_d9_a16)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_d9_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_d9_a32)[256] = { + // clang-format off opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, @@ -975,12 +961,11 @@ const OpFn OP_TABLE(fpu_d9_a32)[256] = opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_da_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_da_a16)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1016,12 +1001,11 @@ const OpFn OP_TABLE(fpu_287_da_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_da_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_da_a32)[256] = { + // clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1057,12 +1041,11 @@ const OpFn OP_TABLE(fpu_287_da_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_da_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_da_a16)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1098,12 +1081,11 @@ const OpFn OP_TABLE(fpu_da_a16)[256] = ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_da_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_da_a32)[256] = { + // clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1139,12 +1121,11 @@ const OpFn OP_TABLE(fpu_da_a32)[256] = ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_686_da_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_686_da_a16)[256] = { + // clang-format off opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, @@ -1180,12 +1161,11 @@ const OpFn OP_TABLE(fpu_686_da_a16)[256] = ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_686_da_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_686_da_a32)[256] = { + // clang-format off opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, @@ -1221,12 +1201,11 @@ const OpFn OP_TABLE(fpu_686_da_a32)[256] = ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_db_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_db_a16)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1262,12 +1241,11 @@ const OpFn OP_TABLE(fpu_287_db_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_db_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_db_a32)[256] = { + // clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1303,12 +1281,11 @@ const OpFn OP_TABLE(fpu_287_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_db_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_db_a16)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1344,12 +1321,11 @@ const OpFn OP_TABLE(fpu_db_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_db_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_db_a32)[256] = { + // clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1385,12 +1361,11 @@ const OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_686_db_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_686_db_a16)[256] = { + // clang-format off opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, @@ -1426,11 +1401,10 @@ const OpFn OP_TABLE(fpu_686_db_a16)[256] = opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_686_db_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_686_db_a32)[256] = { + // clang-format off opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, @@ -1466,52 +1440,47 @@ const OpFn OP_TABLE(fpu_686_db_a32)[256] = opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dc_a16)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_dc_a16)[32] = { + // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dc_a32)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_dc_a32)[32] = { + // clang-format off opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_dc_a16)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_dc_a16)[32] = { + // clang-format off opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_dc_a32)[32] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_dc_a32)[32] = { + // clang-format off opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dd_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_dd_a16)[256] = { + // clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -1547,12 +1516,11 @@ const OpFn OP_TABLE(fpu_287_dd_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_dd_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_dd_a32)[256] = { + // clang-format off opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, @@ -1588,12 +1556,11 @@ const OpFn OP_TABLE(fpu_287_dd_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_dd_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_dd_a16)[256] = { + // clang-format off opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, @@ -1629,12 +1596,11 @@ const OpFn OP_TABLE(fpu_dd_a16)[256] = opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_dd_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_dd_a32)[256] = { + // clang-format off opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, @@ -1670,12 +1636,11 @@ const OpFn OP_TABLE(fpu_dd_a32)[256] = opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_de_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_de_a16)[256] = { + // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -1711,12 +1676,11 @@ const OpFn OP_TABLE(fpu_287_de_a16)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_de_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_de_a32)[256] = { + // clang-format off opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, @@ -1752,12 +1716,11 @@ const OpFn OP_TABLE(fpu_287_de_a32)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_de_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_de_a16)[256] = { + // clang-format off opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, @@ -1793,12 +1756,11 @@ const OpFn OP_TABLE(fpu_de_a16)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_de_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_de_a32)[256] = { + // clang-format off opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, @@ -1834,12 +1796,11 @@ const OpFn OP_TABLE(fpu_de_a32)[256] = opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_df_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_df_a16)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1875,12 +1836,11 @@ const OpFn OP_TABLE(fpu_287_df_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_287_df_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_287_df_a32)[256] = { + // clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1916,12 +1876,11 @@ const OpFn OP_TABLE(fpu_287_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_df_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_df_a16)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -1957,12 +1916,11 @@ const OpFn OP_TABLE(fpu_df_a16)[256] = ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_df_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_df_a32)[256] = { + // clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -1998,12 +1956,11 @@ const OpFn OP_TABLE(fpu_df_a32)[256] = ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_686_df_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_686_df_a16)[256] = { + // clang-format off opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, @@ -2039,12 +1996,11 @@ const OpFn OP_TABLE(fpu_686_df_a16)[256] = opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(fpu_686_df_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(fpu_686_df_a32)[256] = { + // clang-format off opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, @@ -2080,12 +2036,11 @@ const OpFn OP_TABLE(fpu_686_df_a32)[256] = opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(nofpu_a16)[256] = -{ -// clang-format off +const OpFn OP_TABLE(nofpu_a16)[256] = { + // clang-format off op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, @@ -2121,12 +2076,11 @@ const OpFn OP_TABLE(nofpu_a16)[256] = op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, op_nofpu_a16, -// clang-format on + // clang-format on }; -const OpFn OP_TABLE(nofpu_a32)[256] = -{ -// clang-format off +const OpFn OP_TABLE(nofpu_a32)[256] = { + // clang-format off op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, @@ -2162,7 +2116,7 @@ const OpFn OP_TABLE(nofpu_a32)[256] = op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, op_nofpu_a32, -// clang-format on + // clang-format on }; #endif From dd339ec1919ebd070f11d947c04d23f859c24069 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 19 Nov 2022 11:23:33 -0500 Subject: [PATCH 6/6] more clang-formatting in codegen & codegen_new --- src/codegen/codegen_ops.c | 85 +++---- src/codegen/codegen_ops_jump.h | 408 ++++++++++++++++----------------- src/codegen_new/codegen_ops.c | 76 +++--- 3 files changed, 272 insertions(+), 297 deletions(-) diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index 0ae102d24..dc5c9c4ae 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -32,9 +32,8 @@ #include "codegen_ops_stack.h" #include "codegen_ops_xchg.h" -RecompOpFn recomp_opcodes[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, @@ -78,12 +77,11 @@ RecompOpFn recomp_opcodes[512] = /*d0*/ ropD0, ropD1_l, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, NULL, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, ropF6, ropF7_l, NULL, NULL, ropCLI, ropSTI, ropCLD, ropSTD, ropFE, ropFF_32 -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_0f[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_0f[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -127,13 +125,11 @@ RecompOpFn recomp_opcodes_0f[512] = /*d0*/ NULL, ropPSRLW, ropPSRLD, ropPSRLQ, NULL, ropPMULLW, NULL, NULL, ropPSUBUSB, ropPSUBUSW, NULL, ropPAND, ropPADDUSB, ropPADDUSW, NULL, ropPANDN, /*e0*/ NULL, ropPSRAW, ropPSRAD, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, ropPSLLW, ropPSLLD, ropPSLLQ, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, -// clang-format on + // clang-format on }; - -RecompOpFn recomp_opcodes_d8[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_d8[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, @@ -177,12 +173,11 @@ RecompOpFn recomp_opcodes_d8[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_d9[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_d9[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -226,12 +221,11 @@ RecompOpFn recomp_opcodes_d9[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFCHS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLD1, ropFLDL2T, ropFLDL2E, ropFLDPI, ropFLDEG2, ropFLDLN2, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_da[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_da[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, @@ -275,12 +269,11 @@ RecompOpFn recomp_opcodes_da[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_db[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_db[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -324,12 +317,11 @@ RecompOpFn recomp_opcodes_db[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_dc[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_dc[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, @@ -373,12 +365,11 @@ RecompOpFn recomp_opcodes_dc[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_dd[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_dd[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -422,12 +413,11 @@ RecompOpFn recomp_opcodes_dd[512] = /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_de[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_de[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, @@ -471,12 +461,11 @@ RecompOpFn recomp_opcodes_de[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_df[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_df[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -520,12 +509,11 @@ RecompOpFn recomp_opcodes_df[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_REPE[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_REPE[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -569,12 +557,11 @@ RecompOpFn recomp_opcodes_REPE[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_REPNE[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_REPNE[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -618,5 +605,5 @@ RecompOpFn recomp_opcodes_REPNE[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; diff --git a/src/codegen/codegen_ops_jump.h b/src/codegen/codegen_ops_jump.h index 274eef24d..f5c66dd1b 100644 --- a/src/codegen/codegen_ops_jump.h +++ b/src/codegen/codegen_ops_jump.h @@ -1,256 +1,256 @@ -static uint32_t ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJMP_r8(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fetchdat & 0xff; + uint32_t offset = fetchdat & 0xff; - if (offset & 0x80) - offset |= 0xffffff00; + if (offset & 0x80) + offset |= 0xffffff00; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+1+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 1 + offset); - return -1; + return -1; } -static uint32_t ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJMP_r16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint16_t offset = fetchdat & 0xffff; + uint16_t offset = fetchdat & 0xffff; - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, (op_pc+2+offset) & 0xffff); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, (op_pc + 2 + offset) & 0xffff); - return -1; + return -1; } -static uint32_t ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJMP_r32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fastreadl(cs + op_pc); + uint32_t offset = fastreadl(cs + op_pc); - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.pc, op_pc+4+offset); + STORE_IMM_ADDR_L((uintptr_t) &cpu_state.pc, op_pc + 4 + offset); - return -1; + return -1; } - -static uint32_t ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropJCXZ(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fetchdat & 0xff; + uint32_t offset = fetchdat & 0xff; - if (offset & 0x80) - offset |= 0xffffff00; + if (offset & 0x80) + offset |= 0xffffff00; - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - TEST_ZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - TEST_ZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } + if (op_32 & 0x200) { + int host_reg = LOAD_REG_L(REG_ECX); + TEST_ZERO_JUMP_L(host_reg, op_pc + 1 + offset, 0); + } else { + int host_reg = LOAD_REG_W(REG_CX); + TEST_ZERO_JUMP_W(host_reg, op_pc + 1 + offset, 0); + } - return op_pc+1; + return op_pc + 1; } -static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +static uint32_t +ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - uint32_t offset = fetchdat & 0xff; + uint32_t offset = fetchdat & 0xff; - if (offset & 0x80) - offset |= 0xffffff00; + if (offset & 0x80) + offset |= 0xffffff00; - if (op_32 & 0x200) - { - int host_reg = LOAD_REG_L(REG_ECX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_L_RELEASE(host_reg); - TEST_NONZERO_JUMP_L(host_reg, op_pc+1+offset, 0); - } - else - { - int host_reg = LOAD_REG_W(REG_CX); - SUB_HOST_REG_IMM(host_reg, 1); - STORE_REG_W_RELEASE(host_reg); - TEST_NONZERO_JUMP_W(host_reg, op_pc+1+offset, 0); - } + if (op_32 & 0x200) { + int host_reg = LOAD_REG_L(REG_ECX); + SUB_HOST_REG_IMM(host_reg, 1); + STORE_REG_L_RELEASE(host_reg); + TEST_NONZERO_JUMP_L(host_reg, op_pc + 1 + offset, 0); + } else { + int host_reg = LOAD_REG_W(REG_CX); + SUB_HOST_REG_IMM(host_reg, 1); + STORE_REG_W_RELEASE(host_reg); + TEST_NONZERO_JUMP_W(host_reg, op_pc + 1 + offset, 0); + } - return op_pc+1; + return op_pc + 1; } -static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - CALL_FUNC((uintptr_t)CF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); + CALL_FUNC((uintptr_t) CF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); } -static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - int host_reg; + int host_reg; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ZN16: - case FLAGS_ZN32: - case FLAGS_ADD8: - case FLAGS_ADD16: - case FLAGS_ADD32: - case FLAGS_SUB8: - case FLAGS_SUB16: - case FLAGS_SUB32: - case FLAGS_SHL8: - case FLAGS_SHL16: - case FLAGS_SHL32: - case FLAGS_SHR8: - case FLAGS_SHR16: - case FLAGS_SHR32: - case FLAGS_SAR8: - case FLAGS_SAR16: - case FLAGS_SAR32: - case FLAGS_INC8: - case FLAGS_INC16: - case FLAGS_INC32: - case FLAGS_DEC8: - case FLAGS_DEC16: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - if (not) - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ZN16: + case FLAGS_ZN32: + case FLAGS_ADD8: + case FLAGS_ADD16: + case FLAGS_ADD32: + case FLAGS_SUB8: + case FLAGS_SUB16: + case FLAGS_SUB32: + case FLAGS_SHL8: + case FLAGS_SHL16: + case FLAGS_SHL32: + case FLAGS_SHR8: + case FLAGS_SHR16: + case FLAGS_SHR32: + case FLAGS_SAR8: + case FLAGS_SAR16: + case FLAGS_SAR32: + case FLAGS_INC8: + case FLAGS_INC16: + case FLAGS_INC32: + case FLAGS_DEC8: + case FLAGS_DEC16: + case FLAGS_DEC32: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + if (not ) + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)ZF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - break; - } + case FLAGS_UNKNOWN: + CALL_FUNC((uintptr_t) ZF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + break; + } } -static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - CALL_FUNC((uintptr_t)VF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); + CALL_FUNC((uintptr_t) VF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); } -static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - CALL_FUNC((uintptr_t)PF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); + CALL_FUNC((uintptr_t) PF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); } -static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void +BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not ) { - int host_reg; + int host_reg; - switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) - { - case FLAGS_ZN8: - case FLAGS_ADD8: - case FLAGS_SUB8: - case FLAGS_SHL8: - case FLAGS_SHR8: - case FLAGS_SAR8: - case FLAGS_INC8: - case FLAGS_DEC8: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { + case FLAGS_ZN8: + case FLAGS_ADD8: + case FLAGS_SUB8: + case FLAGS_SHL8: + case FLAGS_SHR8: + case FLAGS_SAR8: + case FLAGS_INC8: + case FLAGS_DEC8: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + AND_HOST_REG_IMM(host_reg, 0x80); + if (not ) + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_ZN16: - case FLAGS_ADD16: - case FLAGS_SUB16: - case FLAGS_SHL16: - case FLAGS_SHR16: - case FLAGS_SAR16: - case FLAGS_INC16: - case FLAGS_DEC16: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x8000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + case FLAGS_ZN16: + case FLAGS_ADD16: + case FLAGS_SUB16: + case FLAGS_SHL16: + case FLAGS_SHR16: + case FLAGS_SAR16: + case FLAGS_INC16: + case FLAGS_DEC16: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + AND_HOST_REG_IMM(host_reg, 0x8000); + if (not ) + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_ZN32: - case FLAGS_ADD32: - case FLAGS_SUB32: - case FLAGS_SHL32: - case FLAGS_SHR32: - case FLAGS_SAR32: - case FLAGS_INC32: - case FLAGS_DEC32: - host_reg = LOAD_VAR_L((uintptr_t)&cpu_state.flags_res); - AND_HOST_REG_IMM(host_reg, 0x80000000); - if (not) - TEST_ZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(host_reg, op_pc+pc_offset+offset, timing_bt); - break; + case FLAGS_ZN32: + case FLAGS_ADD32: + case FLAGS_SUB32: + case FLAGS_SHL32: + case FLAGS_SHR32: + case FLAGS_SAR32: + case FLAGS_INC32: + case FLAGS_DEC32: + host_reg = LOAD_VAR_L((uintptr_t) &cpu_state.flags_res); + AND_HOST_REG_IMM(host_reg, 0x80000000); + if (not ) + TEST_ZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(host_reg, op_pc + pc_offset + offset, timing_bt); + break; - case FLAGS_UNKNOWN: - CALL_FUNC((uintptr_t)NF_SET); - if (not) - TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - else - TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); - break; - } + case FLAGS_UNKNOWN: + CALL_FUNC((uintptr_t) NF_SET); + if (not ) + TEST_ZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + else + TEST_NONZERO_JUMP_L(0, op_pc + pc_offset + offset, timing_bt); + break; + } } - -#define ropBRANCH(name, func, not) \ -static uint32_t rop ## name(uint8_t opcode, uint32_t fetchdat, \ - uint32_t op_32, uint32_t op_pc, \ - codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xff; \ - \ - if (offset & 0x80) \ - offset |= 0xffffff00; \ - \ - func(1, op_pc, offset, not); \ - \ - return op_pc+1; \ -} \ -static uint32_t rop ## name ## _w(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fetchdat & 0xffff; \ - \ - if (offset & 0x8000) \ - offset |= 0xffff0000; \ - \ - func(2, op_pc, offset, not); \ - \ - return op_pc+2; \ -} \ -static uint32_t rop ## name ## _l(uint8_t opcode, \ - uint32_t fetchdat, uint32_t op_32, \ - uint32_t op_pc, codeblock_t *block) \ -{ \ - uint32_t offset = fastreadl(cs + op_pc); \ - \ - func(4, op_pc, offset, not); \ - \ - return op_pc+4; \ -} +#define ropBRANCH(name, func, not ) \ + static uint32_t rop##name(uint8_t opcode, uint32_t fetchdat, \ + uint32_t op_32, uint32_t op_pc, \ + codeblock_t *block) \ + { \ + uint32_t offset = fetchdat & 0xff; \ + \ + if (offset & 0x80) \ + offset |= 0xffffff00; \ + \ + func(1, op_pc, offset, not ); \ + \ + return op_pc + 1; \ + } \ + static uint32_t rop##name##_w(uint8_t opcode, \ + uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t offset = fetchdat & 0xffff; \ + \ + if (offset & 0x8000) \ + offset |= 0xffff0000; \ + \ + func(2, op_pc, offset, not ); \ + \ + return op_pc + 2; \ + } \ + static uint32_t rop##name##_l(uint8_t opcode, \ + uint32_t fetchdat, uint32_t op_32, \ + uint32_t op_pc, codeblock_t *block) \ + { \ + uint32_t offset = fastreadl(cs + op_pc); \ + \ + func(4, op_pc, offset, not ); \ + \ + return op_pc + 4; \ + } // clang-format off ropBRANCH(JB, BRANCH_COND_B, 0) diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 2ac4a83d6..3fadd4a13 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -26,9 +26,8 @@ #include "codegen_ops_shift.h" #include "codegen_ops_stack.h" -RecompOpFn recomp_opcodes[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropADD_b_rmw, ropADD_w_rmw, ropADD_b_rm, ropADD_w_rm, ropADD_AL_imm, ropADD_AX_imm, ropPUSH_ES_16, ropPOP_ES_16, ropOR_b_rmw, ropOR_w_rmw, ropOR_b_rm, ropOR_w_rm, ropOR_AL_imm, ropOR_AX_imm, ropPUSH_CS_16, NULL, @@ -72,13 +71,11 @@ RecompOpFn recomp_opcodes[512] = /*d0*/ ropD0, ropD1_l, ropD2, ropD3_l, NULL, NULL, NULL, ropXLAT, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropLOOPNE, ropLOOPE, ropLOOP, ropJCXZ, NULL, NULL, NULL, NULL, ropCALL_r32, ropJMP_r32, ropJMP_far_32, ropJMP_r8, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropCMC, ropF6, ropF7_32, ropCLC, ropSTC, ropCLI, ropSTI, ropCLD, ropSTD, ropINCDEC, ropFF_32 -// clang-format on + // clang-format on }; - -RecompOpFn recomp_opcodes_0f[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_0f[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -144,11 +141,10 @@ RecompOpFn recomp_opcodes_0f[512] = /*e0*/ NULL, NULL, NULL, NULL, NULL, ropPMULHW, NULL, NULL, ropPSUBSB, ropPSUBSW, NULL, ropPOR, ropPADDSB, ropPADDSW, NULL, ropPXOR, /*f0*/ NULL, NULL, NULL, NULL, NULL, ropPMADDWD, NULL, NULL, ropPSUBB, ropPSUBW, ropPSUBD, NULL, ropPADDB, ropPADDW, ropPADDD, NULL, #endif -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_3DNOW[256] = -{ +RecompOpFn recomp_opcodes_3DNOW[256] = { // clang-format off #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 0 @@ -174,12 +170,11 @@ RecompOpFn recomp_opcodes_3DNOW[256] = /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, #endif -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_d8[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_d8[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, @@ -223,12 +218,11 @@ RecompOpFn recomp_opcodes_d8[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, /*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_d9[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_d9[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -272,12 +266,11 @@ RecompOpFn recomp_opcodes_d9[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ ropFCHS, ropFABS, NULL, NULL, ropFTST, NULL, NULL, NULL, ropFLD1, NULL, NULL, NULL, NULL, NULL, ropFLDZ, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSQRT, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_da[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_da[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIADDl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, ropFIMULl, @@ -321,12 +314,11 @@ RecompOpFn recomp_opcodes_da[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFUCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_db[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_db[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, ropFILDl, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -370,12 +362,11 @@ RecompOpFn recomp_opcodes_db[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_dc[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_dc[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, @@ -419,12 +410,11 @@ RecompOpFn recomp_opcodes_dc[512] = /*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, /*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, /*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_dd[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_dd[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -468,12 +458,11 @@ RecompOpFn recomp_opcodes_dd[512] = /*d0*/ ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFST, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, ropFSTP, /*e0*/ ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOM, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, ropFUCOMP, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_de[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_de[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIADDw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, ropFIMULw, @@ -517,12 +506,11 @@ RecompOpFn recomp_opcodes_de[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFCOMPP, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, /*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, -// clang-format on + // clang-format on }; -RecompOpFn recomp_opcodes_df[512] = -{ -// clang-format off +RecompOpFn recomp_opcodes_df[512] = { + // clang-format off /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -566,5 +554,5 @@ RecompOpFn recomp_opcodes_df[512] = /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*e0*/ ropFSTSW_AX, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -// clang-format on + // clang-format on };